游戏中的drawcalls值

来源:互联网 发布:引力的本质 知乎 编辑:程序博客网 时间:2024/04/28 02:11

Drawcalls:这个东西值越小,你的游戏性能越好

介绍:在游戏中每一个被展示的独立的部分都被放在了一个特别的包中,我们称之为“描绘指令”(drawcall),然后这个包传递到3D部分在屏幕上呈现出来。这就和你希望你的亲友收到准备好的圣诞礼物需要包装好然后穿过城市准时放在他应该出现的地方一样没什么不同。你的CPU来完成包装和传递他们的活,同时会消耗很多的带宽,所以最终分配好这些关键性资源很重要。目前,真正可怕的事情是从描绘指令消耗远景开始,每一个独立的飞溅到地板上的血迹和一个角色或者一具死尸消耗的字节是一样的多的:他们都消耗同样的描绘指令。除此之外,没有什么更多的差别

降低DrawCalls:

那么如何降低 draw call呢??那么我们就用到Culling(剔除)技术。如果不应用这个技术,电脑是不管3721把场景里所有的东西都送去渲染的。看得见的也渲染,看不见得照样也送去渲染。很傻是吧,那咋办呢。得告诉电脑,那个你
看得见的渲染,看不见的就算了。于是就有了
1.视锥体剔除(Frustum Culling)这个unity系统自带了好像,就不用操心了。
2.遮挡剔除(Occlusion Culling)

渲染调用(Drawcalls

        每个物体的一个不同的材质都会引起一个单独的Drawcall调用。每一次Drawcall都会引起引擎的一次额外开销,所以在关卡任何点观察时都要避免超过2000次的Drawcalls

        不同的材质应尽量少的使用

        合并一些纹理(例如:如果你在同一个物体使用使用了2个不同的512x256的纹理,应该把它们合并到1512x512的纹理里)

        正方形的纹理会更好的应用到纹理流

        每个物体尽可能使用越少的不同材质,对象的每一个材质都会引起至少2次的Drwacall,如果开启阴影就是3

        延迟渲染使用,延迟渲染在CPU方面的开销比前台渲染开销要小的多,主要开销只在GPU渲染方面。而之前前台渲染的多次Drawcall可以用延迟渲染统一的一次屏幕Drawcall替代。

 

 

 

场景复杂度

        通过关闭的门将房间隔离开

        使用过渡区域

        为没有遮蔽的环境使用雾效

        对于大物体使用Visblocking/occluders

        在特别多对象的区域调整减小可见区域

        删除player看不到的地型

        平滑地表以减少顶点密度

        为每个物体调整可见范围

        设置最大drawcalls警戒值为2000,或者更小

        地表尽量使用越少纹理越好

        避免多种材质重叠

        不要覆盖多个非常大的透明层(transparent)或者添加层(additive)

        为美术资源设置合适距离的LOD范围。

CPU性能

        使用尽量少的复杂的材质(性能成本便宜的)

        cbuffer中尽量少的三角形(节约drawcalls,减少drawcalls的冲突)

        限制cbuffer中的覆盖的区域

        减少动画角色的骨骼数

        不要使用角色动画模糊(蒙皮需要更多的骨骼)

        谨慎使用texturestreaming(需要解压缩)

        尽可能少的在天气效果中使用通明混合的物体(CPU计算雾效的近似值)

        物理代理体尽量使用三角形(要做碰撞检测)

        谨慎使用可破坏的物体

GPU性能

        与分辨率无关的:

        使用尽量少的顶点渲染.(每个顶点是一个独特的位置和纹理坐标点)

        使用一个不太复杂的顶点格式

        使用尽量少的会投射阴影的灯光

        谨慎使用Decals

        与分辨率有关的:

        渲染对象在屏幕上占用尽量少的象素

        使用成本较低的pixelshader(较小的灯光,较少的shader特性如反射,简单的shader)

        场景中每一种材质使用尽量少的纹理

        使用廉价的纹理格式(要尽量使用压缩的DXT1,DXT3,3DC/DXT5)

        使用mipmap

        AlphaBlendAlphaTest要慢,而AlphaTest又比不透明渲染的物体要慢

        延迟渲染的灯光要比正常的灯光要廉价,所有的光影响的半径应尽量的小

        如果需要一些灯光在一些区域的时候(如Box区域),这会导致灯光大量的重叠,使用IrradianceVolumes是非常必要的

        尽可能少的同时开启多种后处理效果,另外一种策略是减少后处理效果开启的时间。

        不使用或使用开销小的全屏抗锯齿(MSAA/FSAA)

        使用劲可能少的天气效果

        使用尽量少的地形材质混合。

内存使用:

        使用尽可能少的贴图

        使用一个低分辨率的纹理分辨率

        使用纹理压缩格式(DXT1最好,DXT53dc也是不错的选择)

        使用尽可能少的顶点

        使用尽可能简单的物理替代体

        使用尽可能少的动画

        使用尽可能少的模型或LOD层级

        使用尽可能少的材质和粒子发射器

        使用尽可能少的道路

        谨慎使用贴花

        使用尽可能少的可投射阴影的光源

纹理流:(与纹理传送带宽相关)

        可流化的纹理应该是正方形大小的(宽和高相等如:1x1256x256)最好

        使用尽可能少的不同文理格式用来更好的做纹理池的统一管理

        每个区域尽可能少的使用独特的大纹理来减少I/O带宽的耗费

        严格遵守每平方米texels(个数)的规则(distance streaming是基于它的),使用r_texelspermetter 1来检查它

        不要尝试使用大于512x512的纹理大小(拆分一些大的纹理成小的纹理)

        尝试避免使用小于128x128的纹理单元(这会引起内存碎片),把同一区域的小纹理拼接他们成一个大纹理

        如果你仍坚持使用大的纹理集(textureatlases)(不建议),确保你不会使用这些物理到场景的不同区域(例如植被)

通用的程序性能准则:

        越简单的材质使用越精简的纹理

        附加物(Attachments)应该是可调整的,当在屏幕上过小是应该不显示他们

        眼睛根据距离是要关闭的,以减少眼球渲染上的消耗(如果把渲染眼睛的情况下)

        可摧毁的物体应该尽量让避免过快的散开(我的理解是爆炸的破损物体尽量散落的要慢,不要设置成太小的破坏体?)

        纹理展开时应该使用越少的顶点(展开成大块)

        贴花要谨慎的使用

        制订纹理分辨率(根据不同范围设置适当比例)

        设置阻挡地带体来减少物体渲染个数

        静态场景中使用Protals可以带来更好的效率

        Blocky geometry helps to get more for the same vertexcount.(理解不了)

        重用几何体与纹理来减少内存使用

        避免在场景中使用独特的细节(尤其是一些复杂的场景中)

        需要多遍渲染的材质层比正常的要慢,谨慎使用

        在导出之前手动做ResetXFromResetTransformations操作,如果不做,这些值会被引擎检查出来生成断言,比如物理模型与渲染几何体不匹配。

        原点应该在物体的包裹盒内部以避免与预期不一直的渲染结果

        跟踪解决控制台输入窗口显示的所有关卡错误级别的错误。

渲染调用(Drawcalls

        每个物体的一个不同的材质都会引起一个单独的Drawcall调用。每一次Drawcall都会引起引擎的一次额外开销,所以在关卡任何点观察时都要避免超过2000次的Drawcalls

        不同的材质应尽量少的使用

        合并一些纹理(例如:如果你在同一个物体使用使用了2个不同的512x256的纹理,应该把它们合并到1512x512的纹理里)

        正方形的纹理会更好的应用到纹理流

        每个物体尽可能使用越少的不同材质,对象的每一个材质都会引起至少2次的Drwacall,如果开启阴影就是3

        延迟渲染使用,延迟渲染在CPU方面的开销比前台渲染开销要小的多,主要开销只在GPU渲染方面。而之前前台渲染的多次Drawcall可以用延迟渲染统一的一次屏幕Drawcall替代。

顶点个数

        在引擎中UV边界会增加顶点个数,使用尽量少的UV边界

        顶点法向量会在一些硬边被分割,保证平滑的多边形减少硬边的数量

物理代理

        良好的物理代理在降低CPU物理计算时间上是非常重要的,如果没有物理代理性能会变慢

        使用简单的物理代理体替代渲染模型来处理物理计算,减少CPU物理计算时间

        渲染几何体的物理计算应该只被应用于一些可破坏的三维体,如可破坏的树干

        物理代理替应尽量使用(图元)Primitives

        尽可能利用粗糙的物体代理体处理角色碰撞和渲染集合体与子弹的碰状检测

        为每个物理代理替使用一组平滑体(只有软边缘)

        在材质编辑器的3d Package中设置物理类型(Set the proper physics type in thematerial edtior of the 3d package

闭塞代理

        为大的物体设置角色视觉遮挡,使用闭塞代理替,使用单面的闭塞代理(因为默认多边型被视为双面),尽可能的简单,越少三角形越好

物体的LOD

        为每个美术资源设置LOD层级,每个LOD的层级中的多边形个数必须至少减少P以上。利用3DMAXdInstancingreduction修改器

        减少LOD岑寂的材质数于节省Drawcalls

        良好的LOD是的良好性能和良好资源外观的关键。

材质设置

        使用尽可能少的材质数量

        合并纹理减少材质数和纹理提取

        保持所有纹理使用CryTIF格式

使用128/128/128作为默认漫反射颜色

        使用简单的灰色128/128/128或快速的色彩纹理做早期的纹理大小的实验,以获取一个合适的内存开销的解决方案

        确保所有纹理都做过性能检测

植被

        在室外游戏中,植被是一个植被覆盖场景中非常大的开销,确保每棵数不超过12drawcalls

        减少植被物体的材质数以节省Drawcalls

        只使用最优化的shader在植被物体上

        减少多边型个数,因为这些物体会被在屏幕上绘制很多遍

        合并文理以减少材质数和最少的纹理提取(texturefetches

        为树叶添加多边型以匹配文理减少overdraw(遮挡绘制),在树干上使用面片

粒子

        尽可能使粒子特效有效,因为他们会带来很大的开销,对性能有很大影响,此外,尽可能的在不影响视觉的条件下用简单粒子替代标准粒子以减少性能开销

FrameTime:

        如果你的FrameTime的目标是每秒30帧,那么每帧的消耗不应该超过33耗秒。

        可以使用r_DisplayInfo2来检测帧时间,或者开启性能评测模式(profile =1)。

        帧速率 = 1.0/1秒中的帧时间。例如1.0/0.033(3) = 30

        GPU时间是非常依赖于屏幕的分辨率,如果使用FSAArender target的格式,例如720P(1280x720)并且HDR关闭。越高的设置,性能越差。

        具体而言,这以为着对于XBOX360,如果你花费5毫秒做Zpass,6毫秒做一般pass,10毫秒做阴影处理(如果开启这个功能的话),这加起来大概花费21毫秒,理论上GPU上的帧速率不会超过47帧。

非延迟渲染光照的开销

        太阳光的渲染使用一个简单的Pass

        点光源的渲染使用一个单独的Pass,可以被合并,最多一个Pass处理4盏灯

        聚光灯渲染总是使用单独的pass

        这以为着如果你场景有阳光,你添加一个点光源,对于每个物体会带来额外的Drawcalls的光源影响。额外的Drawcall开销意味着更多的数据需要被处理在CPU方面,每个drawcall会带来更多的填充率开销

限制纹理数

        Shaders读取纹理对于主机类和老PC硬件是非常昂贵的

        尽量使用DiffuseAlphaShaderGloss选项来替代发光贴图(GlossMap)。这将节省一个着色器的纹理读取。你可以安全的使用不必担心任何质量的损失。如果你使用这个功能并且你的光泽只有单色调,你可以通过高光颜色(SpecularColor)中的颜色材质参数来调整。

        对于植被的shader,使用Merged Textures选项。对于叶子这意味着GlossMap纹理的RGB通道包含了你的透明度RGB通道,GlossMap Alpha将会包含你的灰度光泽信息。对于树干意味着DiffuseAlpha包含了你的灰度光泽信息。请不要忽视这点,因为它对GPU(减少读取开销)和CPU(更少的设置纹理采样的开销)两方面都有好处。

正确的使用Shader着色器选项

        使用Grass ShaderGeneration选项当你做草渲染的时候,这个选项是非常便宜的渲染方法,会生成所有阴影、使用最少的纹理读取,正确的使用这个选项是非常重要的,尤其是对主机游戏。

        使用Decal shadergeneration选项当你把一个材质当作贴花使用时。这对于确保适当的渲染非常重要,比如你要避免Z-fightingZ竞争)在某些硬件和一些渲染条件下。另外延迟渲染(deferredrendering)将只能正常渲染不透明几何体/地表层/贴花,如果没有启动这个选项,你要重新读取Normal Map并再次渲染和计算雾效。

Water/Rivers Volumes

        当使用Water volumes和水下雾效的时候,如果是浅水应将density设置为0。这样可以跳过雾效处理。

        在在小范围可见区域内使用WaterVolumes,如果要覆盖一个大区域的话尽量使用小块进行替代。