移动端 Shader 性能优化常用点

前提:

1. GPU的架构为SIMD(单指令多数据流架构),即在GPU上面执行N个数据和1个数据的效率是一样的,指令相同的情况下。所以并行的计算尽量都放到GPU上。

2. GPU的设计基础为向量计算。(即向量乘法和单个float 的乘法效率一样。【CPU需要执行多次】)

性能可优化点:

1. 合并单个计算为向量运算。

float x;
float y;

x = x *a; y = y * b;

 将上面的写法修改为下面的效率会更高。

float2 v = float2(x,y);
v = v * float2(a,b);

  修改后的写法只需要执行一次。

2. 不要使用条件判断, FOR 语句。(性能不高,会涉及到同步)。

float4 a ;
if( b > 1){
  a.a = 1;
} else {
 a.a = 0.5;
}

  上面的条件判断可以使用 内置函数 step 进行替换。

flaot4 a;

float t = step(b, 1.0);
a = tmp * 0.5 + (1.0 - tmp);

  替换的根本原因在于动态分支

3. 尽可能使用内置函数。(内置函数大部分都使用了GPU的特殊特性)。

  高级函数,如非必要,尽量不要使用,如 sin,cos, sinh, cosh等。( Asin, Acos, Atan非常高。)

4. swizzle 的效率高于单步赋值。

float4 a = float4(1.0, 1.0, 1.0, 1.0);

a.w = 2.0;
a.z = 2.0;

  上面的代码修改为下面的效率更高。

float4 a = float4(1.0, 1.0, 1.0, 1.0);
a.wz= float2(2.0, 2.0);

  

5. 如果非必要,尽量不使用高精度。(高精度32位,中等精度为16位,低精度为12位。)

  附:降低精度在某些情况下不能起到提升性能的作用。

6. 只计算需要的东西。运算尽量放在VS或者脚本中进行。

  原因:只计算需要的东西, 可以减少传输的数据量,避免过多的顶点计算,如:过多的光照,或者光照太复杂。

  通常情况下,需要渲染的像素比顶点数多,而顶点数又比物体数多很多。所以如果可以,尽量将运算从 FS 移到 VS,或直接通过 script 来设置某些固定值;

  并不是所有的计算都适合放到脚本中进行,(CPU的计算结果传递给GPU里面也有性能消耗)

7. 其他

  alpha test, clip , Color Mask 慎用。不同平台上消耗不一样,部分机型可能性能会非常差。

=========================以下内容为转载=============================

定位渲染通道瓶颈的方法
转自:http://blog.csdn.net/rabbit729/article/details/6398343

一般来说, 定位渲染通道瓶颈的方法就是改变渲染通道每个步骤的工作量, 如果吞吐量也改变了, 那个步骤就是瓶颈.。找到了瓶颈就要想办法消除瓶颈, 可以减少该步骤的工作量, 增加其他步骤的工作量。
  一般在光栅化之前的瓶颈称作”transform bound”, 三角形设置处理后的瓶颈称作”fill bound”

定位瓶颈的办法:
1. 改变帧缓冲或者渲染目标(Render Target)的颜色深度(16 到 32 位), 如果帧速改变了, 那么瓶颈应该在帧缓冲(RenderTarget)的填充率上。
2. 否则试试改变贴图大小和贴图过滤设置, 如果帧速变了,那么瓶颈应该是在贴图这里。
3. 否则改变分辨率.如果帧速改变了, 那么改变一下pixel shader的指令数量, 如果帧速变了, 那么瓶颈应该就是pixel shader. 否则瓶颈就在光栅化过程中。
4. 否则, 改变顶点格式的大小, 如果帧速改变了, 那么瓶颈应该在显卡带宽上。
5. 如果以上都不是, 那么瓶颈就在CPU这一边。

猜你喜欢

转载自www.cnblogs.com/checkway/p/10626292.html