3d的性能问题

我用的cocos2dx 3.4final版,在xcode里面进行开发。

我有个这样的场景,一个没有顶的房间,视角是从顶部俯视房间,房间大小为2200 x 2200,房间里有几个小人(房间和小人都是立方体风格,面数和顶数都很低,调试信息显示出来只有348 GL verts,5 GL call)。
我想要做成天天过马路那种风格。

现在的问题主要有两个:
1.帧率太低,我发现当我把光照加上,同时设置camera的位置让房间大小显示出来刚好和手机屏幕差不多一样大时,在ipad上帧率只有30了(模拟器上只有8)。
2.加了光照以后模拟器上的显示效果和真机上的显示效果有较大差异,主要是亮度上的差异。

关于第一个问题
把光照加上对性能有影响,这个我倒是能理解,加了光照毕竟多了不少计算,如果引擎图形处理这块优化做得不是很好的话出现这种情况也算正常。
如果去掉光照帧率又变回60,但是我发现不加光照的话3d对象表面的明暗体现不出来,所以还不能把光照关闭了。
于是我试着把Camera的位置设置得离房间比之前远一倍,这时候屏幕上显示出来的房间只有原来1/4大小,这种情况下帧率也变回到60了,我对3d技术不懂,不理解为什么同一个对象Camera离得近和离得远对帧率的影响会这么大,还盼大牛能指教。此外,虽然能通过把Camera调远来提高帧率,但这完全不现实啊,手机屏幕本身就那么小了,显示出来的东西再小点完全没法玩了。
如果觉得30的帧率也够的人那就啥也别说了,毕竟这么简单的场景,3d对象顶点数也这么少的情况下如果都不能满帧的话都不敢再往里面加东西了,最后做出来的东西也只能是demo了。
要如何才能做到让房间显示大小和屏幕一样大并且开启光照,帧率也能满帧呢?

关于第二个问题
我不知道是不是我建的模型的问题还是引擎自身的问题,我用的是blender软件进行建模的,我发现引擎自带的例子里Light map test里面的模型都是灰白色的,也不知道贴了图没有。

这是我的测试数据
机型:HTC S510B
总面数:5784(3D)+670(2D)
模型数:主角x1 怪物x5 地形x1
稳定帧数:40+
引擎版本:cocos2dx-3.1
是否开启光照:是
总结:cocos2dx做"天天过马路"类型的游戏性能是没有任何问题的

地形是3d的还是只是一张图片呢?你现在东西也很少,我不知道你手机的性能怎么样,但是东西这么少帧率就不能满帧了再多加些东西会怎么样呢?天天过马路看着简单,但是一个屏幕里面场景不小元素也很多,我真的有点怀疑如果是我这种水平的人用cocos2dx做天天过马路这个游戏能流畅运行。

我这是真实地形不是一张图,还有我的模型大部分是动态模型,顶点和法线是要逐帧更新的(性能瓶颈),"天天过马路"真的有那么简单吗。

动态模型是指有骨骼动画的模型吗?我的小人都加了骨骼动画,我今天看了下另外一个开源免费的3d引擎,叫gameplay3d,他里面有个赛车的例子,很大一个场景,汽车在里面跑的时候都能满帧。不知道是不是cocos2dx目前3d这块优化做得还不够好。

光照是像素的光照,比顶点光照费多了,和屏幕的分辨率关系很大,这是普遍现象。
另外,手机游戏,都是把光影画在贴图上,或者用烘焙。
打开实时像素光照的,手机上也就高端,屏幕720p以下还能跑跑,发热巨大。

《Blocky Roads》是一款开阔场景的3d像素风格游戏上过推荐的,他就是cocos2dx做的,在低端手机上面都能很流畅运行,我的个人观点:小型3d游戏如果帧数不高多半是自己的问题而不是引擎的瓶颈。

你是对的,有哪些需要注意的地方呢?

信息量好大,我先了解一下,感谢!

我试了下把光影绘制到贴图上这种方式。我把大的场景的贴图做成了光影形式,小的精灵还是保持原来的不变,也就是说我想对场景(也就是房间)不使用动态光照,而只对小的精灵使用动态光照,可是我发现好像无法做到这点,动态像素光照要么就所有对象都用,要么就都不用。比如我只对小的精灵设置了光照mask,对房间不设置光照mask,按道理讲不是应该房间就不参与动态光照计算了吗?可是我这边的结果是不管光照的flag设置成什么,只要房间不设置光照mask它就会参与光照计算,而如果把房间的光照mask设置成和光照的flag不一致则房间显示不出来。
这是什么情况呢?要如何做才能做到我想要的效果呢?

lightmask只是设置了当前node的值,父node的lightmask是不会作用于子node,有可能你的模型是一个node tree,所以你需要根据需要遍历到相应子节点设置lightmask才会用有作用。

我现在的问题不是lightmask不起作用,而是我不想它起作用他也起了作用,比如我在一个场景里有两个Sprite3d a和b,a,b用的都是独立的模型,我现在只想对a使用光照而对b不使用光照。于是我给a设置了和光照相同的lightmask,而b没有设置任何lightmask,我以为这样光照就不会在b上起作用了,可是出来的结果是在b上光照也起作用了。

我的意思就是你的a,b模型可能是由node tree构成的,如果你只是简单的调用sprite3D->setLightMask可能不会作用于真正绘制的节点上,
所以需要:
for each child in sprite3D
child->setLightMask

另外,如果对b你没有设置任何lightmask,默认本来就是接受所有光照,如果要不接受光照,必须设为0.

之前我也试过把b的lightmask设为0,结果b直接黑掉看不见了,是我哪里漏掉什么了吗?

你可能没有设置AmbientLight,lightmask为0,当然是不会接受任何光源,所以就是黑的,考虑增加AmbientLight,并只对b起作用。

我想让光照只对a起作用而不对b起作用目的是为了减少光照计算以提高程序运行效率,所以虽然你说的这个方法可以让a和b接受不同的光照但是对我这个情况可能不适用。
我之所以想要能做到只对a启用光照而不对b启用光照是因为当屏幕分辨过高时光照像素计算非常耗性能,因此我想能不能做到只对小物体做启用光照,而对场景就使用光照贴图,这样既能提高小物体比如桌球这种球类的表现细节同时又不至于太过影响游戏的性能。