前言:这篇文章主要是把自己使用shader遇到的一些想法和经验总结起来,会一直更新内容。
1.通用编译指令
#pragma vertex name
#pragma fragment name
2.Cg/HLSL的语义,语义是不可省略的,它将告诉系统用户需要输入哪些值以及用户的输出是什么。
POSITION:告诉unity,把模型的顶点坐标输入
SV_POSITION:告诉unity,顶点着色器的输出是裁剪空间中的顶点坐标
SV_Target:它等同于告诉渲染器,把用户的输出颜色存储到一个渲染目标中。
3.数据是怎么来的
填充到输入结构体中的数据,是由使用该材质的Mesh Renderer提供的,在每帧调用draw call时,Mesh render会把它负责渲染的模型数据发送给unity shader。一个模型通常包括了一组三角面片,每个三角面片由三个顶点构成,而每个顶点又包含了一些数据,例如顶点位置,法线,切线,纹理数据,顶点颜色等。
4.顶点着色器和片元着色器如何通信
顶点着色器的输出结构中必须包含一个变量,它的语义是SV_POSITION,否则,渲染器无法得到裁剪空间中的顶点坐标,也就无法把顶点渲染到屏幕上。
注意:顶点着色器是逐顶点的,片元着色器是逐片元的。片元着色器的输入实际上是把顶点着色器的输出进行插值后得到的结果。
5.shader里应该尽量不用分支和循环语句。因为gpu支持大量的算术运算时基于其高并行的硬件结构,但是在处理逻辑时,高并行的优势就没了。
6.每个pass结束时,返回颜色值,都会将每个通道的值截取到1,类似如下操作,finalcol=min(fixed4(1,1,1,1),finalcol);这个一定要注意,要记着它会自动进行这种操作,防止在合并两个pass的时候,由于没有手动进行这种处理而发生错误。