0
点赞
收藏
分享

微信扫一扫

游戏开发56课 性能优化13


 

4.10 Shader优化

  • 避免使用耗时的数学运算。如pow、exp、log、sin、cos、tan等等。
  • 使用更低精度的浮点数。OpenGL ES的浮点数有三种精度:highp(32位浮点), mediump(16位浮点), lowp(8位浮点),很多计算不需要高精度,可以改成低精度浮点。

precision mediump float; // Defines precision for float and float-derived (vector/matrix) types.
uniform lowp sampler2D sampler; // Texture2D() result is lowp.
varying lowp vec4 color;
varying vec2 texCoord; // Uses default mediump precision.

  • 禁用discard操作。原因见4.2.2。
  • 避免重复计算。

precision mediump float;
float a = 0.9;
float b = 0.6;

varying vec4 vColor;

void main()
{
gl_FragColor = vColor * a * b; // a * b每个像素都会计算,导致冗余的消耗。
}

  • 向量延迟计算。

highp float f0, f1;
highp vec4 v0, v1;

v0 = (v1 * f0) * f1; // v1和f0计算后返回一个向量,再和f1计算,多了一次向量计算。
// 改成:
v0 = v1 * (f0 * f1); // 先计算两个浮点数,这样只需跟向量计算一次。

  • 充分利用向量分量掩码。

highp vec4 v0;
highp vec4 v1;
highp vec4 v2;
v2.xz = v0 * v1; // v2只用了xz分量,比v2 = v0 * v1的写法要快。

  • 避免计算数组下标。在shader使用动态下标会导致较大的开销。
  • 警惕动态纹理采样(Dynamic Texture Lookup,也叫Dependent Texture Read)。也就是说在shader中,纹理坐标做了更改,就是动态纹理采样(也称依赖式纹理读取)。在OpenGL ES 2.0的架构下,动态纹理采样会出现较大的性能问题;3.0则没有这问题。详细看​​这里​​。

varying vec2 vTexCoord;
uniform sampler2D textureSampler;

void main()
{
vec2 modifiedTexCoord = vec2(1.0 - vTexCoord.x, 1.0 - vTexCoord.y); // 纹理坐标改变了
gl_FragColor = texture2D(textureSampler, modifiedTexCoord); // 触发了Dynamic Texture Lookup/Dependent Texture Read。
}

  • 避免临时变量。
  • 避免使用for等循环语句。可以尝试展开。
  • 尽量将Pixel Shader计算移到Vertex Shader。例如像素光改成顶点光。
  • 将跟顶点或像素无关的计算移到CPU,然后通过uniform传进来。
  • 分级策略。不同画质不同平台采用不同复杂度的算法。

4.11 UI优化

UI除了资源优化(2.2)之外,可以在渲染上做一些优化措施。

  • 避免不同图集的控件交叉。交叉会增加draw calls,所以要避免。
  • 动态区域和静态区域分离。即文字/道具等动态控件放在同一层,而其它静态的控件尽量放至同一层,可以提高合批的概率。

4.12 其它渲染优化

4.12.1 避免后处理

后处理是场景物体渲染完成后,对渲染纹理做逐像素处理,以便实现各种全屏效果,包含以下效果:

  • 抗锯齿:Anti-aliasing (FXAA & TAA)
  • 环境光散射:Ambient Occlusion
  • 屏幕空间反射:Screen Space Reflection
  • 雾:Fog
  • 景深:Depth of Field
  • 运动模糊:Motion Blur
  • 人眼调节:Eye Adaptation
  • 发光:Bloom
  • 颜色校正:Color Grading
  • 颜色查找表:User Lut
  • 色差:Chromatic Aberration
  • 颗粒:Grain
  • 暗角:Vignette
  • 噪点:Dithering

Unity的后处理栈:

游戏开发56课 性能优化13_python

虽然后处理可以渲染出非常多的很酷很真实的效果,但是消耗也不容小觑。特别是在移动端,由于移动设备硬件架构的特殊设计,会导致更为严重的性能问题,主要原因是:

  • 更慢的依赖式纹理读取(slower dependent texture reads)。关于依赖式纹理读取的解释看​​这里​​。
  • 缺少硬件特性(missing hardware features)。
  • 额外的渲染纹理解析消耗(extra render target resolve costs)。

所以移动游戏要尽量避免使用后处理。

4.12.2 降分辨率

降分辨率是最粗暴最有效的提升渲染性能的方法。由于当前很多智能设备分辨率都是超高清,动辄2K以上,但CPU/GPU却跟不上,如果使用原始屏幕分辨率,就会出现严重的卡帧/掉帧现象。通常可以将屏幕分辨率降到一半,这样渲染纹理/深度Buffer/纹理等等数据都可以缩减到原来的1/4,极大降低了CPU/GPU/带宽各项指标的消耗。

 

举报

相关推荐

0 条评论