Unity Shader的代码编写优化思考

时间:2020-11-28 15:05:48

作为一名技术美术,Shader的性能优化是基本功。
简单的一些,在不影响效果输出的情况下减少变量的精度,避免数据类型的转换。
减少或避免使用幂函数、指数函数、三角函数等复杂的函数运算,使用近似方程。
或者将一些计算写入纹理,使用纹理读取的方式减轻运算量。
这些Tips在工作中可以说都没有什么顾虑去实现。
但是我个人的顾虑是:在Shader编写中,我们可以知道有些计算,是可以放到三个部分中的,比如顶点着色器,片段着色器以及脚本中。顶点着色器和片段着色器,分别是逐顶点和逐像素来进行计算的。而脚本中,是每一帧计算的(Update函数)。
Note:这里指的运算是每一帧针对物体的所有像素的计算结果只有一个固定值的通用计算。
那把计算放到哪里更能优化性能?
顶点着色器:逐顶点计算,计算次数等于顶点数。
片段着色器:逐像素计算,计算次数等于像素数。
脚本:逐帧计算,每帧计算一次。
Note:不考虑模型裁剪和剔除。
从计算次数上来看效率,脚本>顶点着色器>片段着色器。
然而区别是,顶点着色器和片段着色器是Shader内部的计算,运行在GPU上。在非固定的渲染管线下,将计算从片段着色器移动至顶点着色器使得性能得到优化是没有疑问的。而脚本的计算则是运行在CPU上,计算得到的结果传递给GPU也会有性能的开销。这样使用脚本来替代顶点着色器中的计算是否真的能优化性能?
举两个极端的例子:
模型1:超高精度模型,模型顶点数1000W。(Nvidia的技术展示Demo)
模型2:Quad,模型顶点数4。
如果对于模型1,还能肯定的说,脚本效率更高。那么对于模型2,还能这么肯定么?
GPU和CPU的浮点运算性能差距,以及CPU向GPU传值的性能开销,要如何衡量?