UnityShader中的语义相关
语义简介:实际上就是一个表达参数含义的字符串。
应用阶段到顶点着色器时用常用的语义如下:
POSITION:模型空间中的顶点坐标
NORMAL:模型空间中的法线方向
TANGENT:模型空间中的切线方向
TEXCOORDn:模型空间中第n组纹理坐标
COLOR:模型空间中顶点的颜色
顶点着色器传递数据给片元着色器时常用的语义如下:
SV_POSITION:裁剪空间中的顶点坐标
COLOR0:输出第一组顶点颜色,不是必须
COLOR1:输出第二组顶点颜色,不是必须
TEXCOORDn:输出第n组纹理坐标,不是必须
片元着色器输出数据到unity阶段常用的语义如下:
SV_Target:输出值存储到渲染目标中。
语义使用时注意点:
1.unity中有些语义是必须的,有些不是必须的,而且在不同的阶段,语义的必须性不一样,对于不必须的语义,我们可以自定义使用。
2.SV代表的含义是系统数值,在高版本的渲染引擎中会使用到,虽然低版本的渲染引擎也会有类似语义的字符串,但是最好用高版本的,这样可以向下兼容。
3.不同的shader model支持的语义类型各不相同,默认支持的是2.0版本,如果需要自己指定版本,可以使用”#pragmatarget 版本号”来指定。
shader应该注意的差异性:
1.平台差异:不同的平台,坐标系的轴心是不同的,但是unity内部又帮我们处理了这种差异,除非我们开启了抗锯齿功能,并且同时处理多张纹理时,就会出现主纹理和其他纹理的轴心不一致的问题,此时我们需要对其他纹理进行y轴转换,否则采样变换时,结果会是错的。
2.语法差异:由于DirectX中语法检测比较严格,一些OpenGL中通过的语法在DirectX中可能就不能通过,此时就必须要按照DirectX语法来操作shader。比如:float4类型赋值在OpenGL中可以只赋值一个参数,但是在DirectX中必须每个参数都赋值。
3.语义差异:不同的语义之间可能有相同的含义,但是在别的平台可能就不能表达相同的含义了,比如SV_POSITION和POSITION在DirectX和OpenGL平台上都表示齐次裁剪空间输出坐标,但是在PS4上就不是。
shader编写应该遵循的原则:
1.数据类型应该按照从小到大的使用原则,保证数据大小的最优化。
2.规范的语法,因为DirectX,OpenGL中存在不同的语法,所以应该使用两边都支持的语法。
3.规范的语义,因为DirectX,OpenGL中存在不同的语义,所以应该使用两边都支持的语义。
4.避免不必要的计算,因为着色器中寄存器和指令数是有限的,所以不宜计算过于复杂,可以通过制定shader target model大小来支持不同的指令和寄存器数。
5.慎用分支和循环语句,应该GPU中执行分支和循环语句性能会低。
6.不要除以0,因为这会造成一些未知的结果,有些平台会报错,有些平台不报错,但是取值具有随机性,得到结果不正确。