Shader|第五章 开始Unity Shader学习之旅

一.简单顶点/片元着色器
1.指定函数
#pragma vertex vert
#pragma fragment frag

2.POSITION & SV_POSITION & SV_Target 语义
CG/HLSL语义,告诉系统,用户需要哪些输入值 ,以及用户输出是什么
POSITION:float4 v:POSITION 把模型顶点坐标填充到输入参数v中。
SV_POSITION:
告诉顶点着色器,输出的是裁剪空间中的顶点坐标。
顶点着色器的输出结构,必须包含SV_POSITION变量。
SV_Target:把用户输出颜色存储到一个渲染目标中,这里输出到默认的帧缓存中。

3.使用结构体封装输入数据

struct av2
{
float4 vertex:POSITION; //用模型顶点坐标填充vertex
float3 normal:NORMAL; //用模型空间法线方向填充normal
float4 texcoord:TEXCOORD0//用模型第一套纹理坐标填充texcoord
}

4.语义中的数据从哪里来
由材质的Mesh Render组件提供的。
在每帧调用Draw Call的时候,Mesh Render 会把负责渲染的模型数据发送给Unity Shader.

5.顶点着色器和片元着色器之间的通信
顶点着色器是逐顶点调用的,而片元着色器是逐片元调用的。
片元着色器中的输入实际 是把顶点着色器的输出进行插值后得到的结果。



5.使用属性
ShaderLab中属性的类型与CG变量类型之间的匹配关系:
Color,Vector:float4,half4,fixed4
Range,Float:float,half,fixed
2D:sampler2D
Cube:samplerCube
3D:sampler3D

6.内置包含文件
类似于C++头文件,后缀是.cginc,可以使用用#include包含进来。
这样就可以使用Unity为我们提供的一些非常有用的变量和帮助函数。

7.UnityCG.cginc
UnityCG.cginc预定义了很多结构体作为顶点着色器的输入和输出。


8.Unity提供的CG/HLSL语义

顶点到片元:
SV_POSITION: 裁剪空间顶点坐标
【Shader|第五章 开始Unity Shader学习之旅】COLOR0:输出第一组颜色,非必需
COLOR1:输出第二组颜色 ,非必需
TEXCOORD0~TEXTCOORD7: 输出纹理坐标

片元着色器输出:
SV_Target:输出值 存储到渲染目标(render target)


9.调试Shader
1.使用假彩色图像(false-color image)
将需要调试的变量映射到[0,1]之间,把它们作为颜色输出到屏幕上。

2.Visual Studio
Graphics Debug

3.帧调试器(Frame Debug)
Windows->Frame Debug




10.Shader代码优化
1.float,half,fixed
float:32位
half:16位 ,精度-60000~+60000
fixed:11位 ,精度-2~+2

大多数桌面GPU会把所有计算按最高浮点精度进行计算,也就是float,half,fixed在这些平台实际是等价的。
在移动平台GPU上,会有不同的精度范围。
fixed精度实际上只在一些较旧平台有用,大多数现代GPU,内部把fixed和half当成同等精度对待。

2.慎用分支和循环语句
早期GPU不支持在着色器中使用控制语句。
现在虽然可以使用循环分支语句,但是它们和在CPU上有很大不同。
不鼓励在Shader 中使用控制语句,会降低GPU的并行处理操作,性能可能会成倍下降。

解决方法:
2.1 尽量把计算向流水线上端移动
2.2 分支语句中使用的条件变量最好是常数,在Shader运行过程中不会改变
2.3 分支中包含的操作指令数尽可能少。
2.4 分支嵌套层数尽量少。



    推荐阅读