云程环境建设集团网站,互联网广告怎么做,魔方优化大师官网,无域名网站 能否被百度本系列为作者学习UnityShader入门精要而作的笔记#xff0c;内容将包括#xff1a;
书本中句子照抄 个人批注项目源码一堆新手会犯的错误潜在的太监断更#xff0c;有始无终
我的GitHub仓库
总之适用于同样开始学习Shader的同学们进行有取舍的参考。 文章目录 减少需要处… 本系列为作者学习UnityShader入门精要而作的笔记内容将包括
书本中句子照抄 个人批注项目源码一堆新手会犯的错误潜在的太监断更有始无终
我的GitHub仓库
总之适用于同样开始学习Shader的同学们进行有取舍的参考。 文章目录 减少需要处理的顶点数目优化几何体模型的LOD技术遮挡剔除技术 减少需要处理的片元数目控制绘制顺序小心透明物体减少实时光照和阴影 节省带宽减少纹理大小使用分辨率缩放 减少计算复杂度Shader 的LOD技术代码方面的优化 上一节我们描述了如何通过减少DrawCall来减轻CPU的资源调度压力。本章中我们将从其他方面来优化性能
减少需要处理的顶点数目
优化几何体
3D游戏制作离不开3D模型。由于渲染时需要逐顶点逐面片渲染因此优化3D模型是很重要的。
一般的原则是优化模型的网格结构减少模型中的顶点数量面数
有时Unity中显示的顶点数量会超过模型本身的顶点数量。这是由于在GPU看来有时为了计算的需要会将一个顶点拆分为两个顶点主要目的有两个一个是为了分离纹理坐标uv splits另一个是为了产生平滑的边界smoothing splits
它们的本质其实是对于GPU来说的顶点的每一个属性和顶点之间必须是一对一的关系。例如一个立方体它的六个面之间有一些相同的顶点但是这些顶点相对于每个面的纹理坐标就不同了因此就会拆分为多个不同纹理坐标的顶点平滑边界也是类似的。因此一个顶点可能会对应多个法线信息和切线信息。
因此我们需要尽可能减少顶点数量一个建议是——移除不必要的硬边以及纹理衔接避免边界平滑和纹理分离。 模型的LOD技术
另一个减少顶点数目的方法是使用LOD技术LOD技术的原理是为模型准备好几套不同细节程度的模型纹理然后根据摄像机和物体间的距离选择为模型加载的LOD层级Unity就会自动使用对应等级的模型。
一般离得越远则细节程度越低离得越近细节程度越高 遮挡剔除技术
遮挡剔除就是Occlusion Culling就是剔除那些我们看不到的物体面避免计算不必要的资源。
像摄像机自带的Culling效果对层级手动设置的Culling效果包括Shader的背面和正面剔除都是出于这一目的的。
注意区分摄像机的遮挡剔除和视锥体剔除Frustum Culling视锥体剔除是剔除不在摄像机视锥内的物体而遮挡剔除是剔除摄像机视锥内看不见的物体其原理是用一个虚拟摄像机来遍历场景并识别那些物体是可见的哪些是不可见的。
LOD技术和遮挡剔除技术可以同时减少CPU和GPU的负荷CPU可以提交更少的DrawCall而GPU需要处理的顶点和面数也少了。 减少需要处理的片元数目
另一个造成GPU的性能瓶颈的原因是需要处理过多的片元。除了我们之前说的减少模型网格顶点数减少片元外这部分的重点更在于减少OverDraw——即同一个像素的重复绘制。
想象一下有一个B物体挡在了A物体的前面。若我们先渲染A物体再渲染B物体那么同一个像素被渲染了两次显然A物体是没必要渲染的就造成了OverDraw这时我们可以用深度测试来避免这一情况 我们可以再Scene视图下查看overdraw的情况来判断物体之间的遮挡。
控制绘制顺序
为了避免OverDraw 一个重要的优化策略就是控制绘制顺序。由于深度测试的存在如果我们可以保证物体都是从前往后绘制的就可以最大限度减少OverDraw。这是因为在后面绘制的物体由于无法通过深度测试因此不会重复渲染。
在Unity中那些渲染队列数目小于2500的如BackGround GeometryAlphaTest的对象都被认为是不透明的Opaque的物体不透明的物体通常是从前往后绘制的。
而其他队列例如“Transparent”“Overlay等则是从后往前绘制的因为这些队列常常是透明度渲染的这些渲染就比较麻烦为了正确的渲染效果我们往往还需要手动控制渲染顺序。
在开发中我们考虑到摄像机下一些人或物在屏幕上的渲染顺序为它们设置不同的渲染队列将节省很多渲染时间。 小心透明物体
对于半透明物体来说由于它们没有开启深度写入因此如果想要得到正确的渲染结果必须从后往前渲染因此为了正确的渲染效果半透明物体一定会产生overdraw的。
因此如果屏幕上存在大量半透明物体或者粒子效果甚至多层半透明效果相互堆叠的情况就会有大量的OverDraw这是我们需要避免的。特别是GUI对象的渲染常常要用到半透明效果。
对于上述的情况我们可以减少视窗中GUI的面积以减少OverDraw的像素。也可以把GUI的绘制和三维场景的绘制交给不同的摄像机并且三维摄像机的视角范围尽量不要和GUI的相互重叠。 减少实时光照和阴影
实时光照和阴影的计算是很昂贵的我们之前讲光照的时候说过实时光照的渲染特别不属于主光源的部分例如点光源会调用每个照射到的物体上的Pass。导致Pass一下子增多了。
例如一个场景如果包含了3个逐像素的光照而且使用了逐像素的Shader那么很有可能将DrawCall的数量提高3倍。
并且无论是静态批处理还是动态批处理额外的逐像素光照pass都会导致中断批处理
当然游戏是少不了光照的少用实时光不代表不用光照效果我们往往会为模型提前烘焙好一张光照纹理和阴影纹理根据光照方向来进行计算采样来代替实时光照效果。只有某些动态物体才会使用实时光照 节省带宽
大量使用未经压缩的纹理以及使用过大的分辨率都会造成由于带宽引发的性能瓶颈。
减少纹理大小
使用纹理图集atlas可以帮助我们减少DrawCall的数量因为图集中的所有纹理都可以通过一次DrawCall提交除此之外纹理大小也是一个需要考虑的问题。所有纹理的长宽比最好是正方形而且长宽值最好是2的整数幂这样很多的优化策略才能发挥最大的作用。
除此之外我们还可以用多级渐远技术和纹理压缩来优化纹理当勾选了Generate Mip Maps则生成多级渐远纹理和LOD技术相似根据远近来选择渲染的纹理。在GUI和2D游戏中使用的纹理等都应该为纹理生成相应的多级渐远纹理。
纹理压缩同样可以节省带宽不同的GPU架构可能有不同的纹理压缩格式除了有时我们需要纹理特别清晰时例如GUI我们不希望对纹理进行压缩。 使用分辨率缩放
过大的屏幕分辨率和糟糕的GPU也会造成带宽压力大 在特定的设备上我们还需要对程序指定分辨率缩放。 减少计算复杂度
Shader 的LOD技术
Shader的LOD技术和模型的LOD技术类似其原理是当Shader的LOD值小于当前的LOD值该shader才会被使用否则使用了该Shader的物体不渲染。
在未设置LOD值的Shader中LOD是无限大的也就是无论如何都使用。在设定了LOD值之后我们若想要剔除部分复杂计算的Shader就可以通过设置LOD值来剔除方法是使用Shader.maximumLOD或Shader.globalMaximumLOD来设定允许的最大LOD 代码方面的优化
通常来说游戏需要计算的数量排序是游戏对象数量顶点数量像素数量。因此我们应当尽可能将操作放在游戏对象上或者顶点上。
例如之前我们采样坐标时放在了顶点着色器上而非片元着色器就大大提高了计算性能。
以下说的优化策略在某些设备上不成立这很正常
尽量使用低精度的浮点数进行运算。最高精度的float类型用于存储顶点坐标等变量但是像颜色值归一化值这类范围为[0,1]的我们就会使用fixedhalf通常使用与一些标量纹理坐标等变量计算速度大概是float的两倍。尽量避免不同精度间的值转换。特别考虑别在片元着色器中使用高精度计算对于大多数的GPU在数据传递阶段例如用v2f将数据从顶点着色器传递到片元着色器的时候我们尽可能使用少的插值变量例如可以用一个fixed4存储就不用两个fixed2。有些平台例如PowerVR例外 3.尽量不使用全屏的屏幕后处理效果尽量把多个特效合并在一个Pass中
尽量别用if分支语句和for循环语句尽量避免sintanpowlog等复杂数学运算我们可以用查找表来代替尽量不要使用discard