Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说针对虚幻3引擎渲染底层的效率优化,希望能够帮助你!!!。
http://blog.163.com/ding_liang1989/blog/static/168788329201310215359777/
本人新公司的项目用的是虚幻3引擎,终于有幸观摩一下国外的高级货了。半个月代码看下来,感觉虚幻3的代码比OGRE还是有不小的差距的,这里记录一下优化方案。
1、虚幻3在DX API调用上都是直接调用,没有做重复调用判断,这样或多或少影响了运行效率。做重复判断很简单,这里就不写具体代码了,只提一下坑。
A、顶点和索引缓存是不能简单的判重的。
B、SamplerState做判重会导致设备丢失之后效果出错,解决方法是在FD3D9DynamicRHI::UpdateD3DDeviceFromViewports中重置一下所有状态。
结论:没用。
2、静态物件的批次合并。以现在的硬件水平来说,很少有机器不支持vs_3_0了,所以完全可以放心的用hardware instancing。虚幻3中,普通的StaticMeshComponent是单独画的,要用InstancedStaticMeshComponent才会合并渲染。虚幻3在两个地方应用了InstancedStaticMeshComponent,那就是Procedural Building和Foliage(新版植被系统),普通的静态物件,如果重复摆放,则完全可以应用Foliage,只要是Static Mesh就可以,并不一定要是植物。由于虚幻3在画Base Pass之前会画Depth Pre-Pass,所以能够从批次合并当中受益的地方还是比较多的。
3、虚幻3对于USkeletalMesh貌似没有任何批次合并的考虑,效率上只在LOD上下工夫,像DOTA这种类型的游戏,网格LOD是没什么意义的,具体解决方案待定。
4、虚幻3的ProjectedShadow是一种不太常见的阴影技术,这种技术和ShadowMap有一点不同在于要对投影的锥体进行裁剪来决定是否画阴影,这个锥体在裁剪上带来的误差太大了,虚幻3的做法是用硬件遮挡查询(FSceneViewState::IsShadowOccluded)和这个投影锥体来裁剪,很多完全看不到的阴影实际上都在渲染,解决方法:单独给一个阴影的包围盒,裁剪这个包围盒而不是投影锥。
结论:大幅度提升性能(20+到30+)。
5、还是上面所说的阴影问题,ProjectedShadow这种阴影技术渲染的投射与接收的批次数量比是1:1的,也就是说,每渲染一个投射,就必然要渲染一个接收,打个比方,场景中一盏主光产生阴影,100个动态物件摆在一个地表上,设可见的地表Tile数量为N,物件只投射不接收,地表只接收不投射,这是目前MMORPG比较常用的动态阴影方案,那么用ShadowMap就是100个投射批次+N个接收批次,用ProjectedShadow则是100个投射批次+100个接收批次,虽然ProjectedShadow渲染的投影锥是很简单的几何体,远比地表的三角形要少,但过多的增加批次导致效率降低。解决方案暂定为把投影锥的顶点Buffer做动态合并搞成一个批次渲染。这要求投射阴影图尽量的大,因为虚幻3会把这张图划分为不同大小的区域,如果过小,投射阴影图上的部分区域就会被重复绘制,这样会导致断批次。
结论:30帧左右,好CPU,垃圾显卡,代码里强制只画一次接收,基本无提升。
6、虚幻3在D3D9中用16/32位浮点纹理的HDR Buffer的alpha通道来渲染DepthTexture,同时如果不需要HDR效果,我没有找到替代解决方案,浮点纹理作为RenderTarget导致效率大幅度降低,但这张DepthTexture在渲染阴影的时候要用到(具体用来做什么我还没实际看,初步猜测是反算像素的世界坐标),所以必须要有,ARGB8格式的精度显然又不能用来替代。解决方案:在Early-Z阶段打开颜色写,单独给一个RenderTexture来渲染DepthTexture,在渲染阴影的时候把HDR Buffer换成这张DepthTexture,把HDR Buffer换成LDR Buffer。
坑:1、虚幻3用的是W Buffer而不是Z Buffer,所以在VertexShader输出深度的时候不能用Z/W,而是直接用W。
2、在像素Shader返回深度颜色的时候不能简单的返回float4(w, w, w, 1),而是应该调用EncodeFloatW(W)。
3、虚幻3在低配模式是不画Early-Z的,ColorBuffer也是A8R8G8B8,改的时候注意点,别把低配反而改低了。
结论:大幅度提升性能(30+到40+)。
由于开发新引擎,我对优化虚幻3已经没什么欲望了,先就这样吧。
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。