Unity Shader 的形式
01.Unity Shader 的最重要的任务还是指定各种着色器所需的代码.
02.不管哪种形式,真正意义上的 Shader 代码都需要包含在 ShaerLab 语义块中
例:
Shader "MyShader"
{
Properties
{
// 所需要的各种属性.
}
SubShader
{
// 真正意义上的 Shader 代码会出现在这里
// 表面着色器 (Surface Shader) 或者
// 顶点/片元着色器 (Vertex/Fragment Shader) 或者
// 固定函数着色器 (Fixed Function Shader)
}
SubShader
{
// 和上一个 SubShader 类似
}
}
3.4.1 Unity 的宠儿: 表面着色器
01.表面着色器(Surface Shadre), 是Unity 自己创造的一种着色器代码类型.代码量小,渲染代价大.本质和顶点/片元着色器是一致的.表面着色器可以理解为是 Unity 对顶点/片元着色器的更高一层的抽象.
表面着色器示例代码:
Shader "Custom/Simple Surface Shader"
{
SubShader
{
Tags {"RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Lambert
struct Input
{
float4 color : COLOR;
};
void surf (Input IN, inout SurfaceOutput o)
{
o.Albedo = 1;
}
ENDCG
}
Fallback "Diffuse"
}
从这段代码中我们可以看出,表面着色器被定义在 SubShader 语义块 (而非 Pass 语义块) 中的 CGPROGRAM 和 ENDCG 之间.原因是:表面着色器不需要开发者关心使用多少个 Pass,每个 Pass 如何渲染,这些事情 Unity 会在背后为我们处理好.
02.CGPROGRAM 和 ENDCG 之间的代码是使用 CG/HLSL 编写的,也就是说,我们需要把 CG/HLSL 语言嵌套在 ShaderLab 语言中.注意:这里的 CG/HLSL 是 Unity 经封装后提供的,它的语法和标准的 CG/HLSL 语法几乎一样.但是,有些原生的函数和用法 Unity 并没有提供支持.
3.4.2 顶点/片元着色器
01.在 Unity 中,我们可以使用 CG/HLSL 语言来编写 顶点/片元着色器(Vertex/Fragment Shader).它们更加复杂,但灵活性也更高.
示例代码:
Shader "Custom/Simple VertexFragment Shader"
{
SubShader
{
pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float4 vert(float4 v : POSITION) : SV_POSITION
{
return mul (UNITY_MATRIX_MAP,v);
}
fixed4 frag() : SV_Target
{
return fixed4(1.0,0.0,0.0,1.0);
}
ENDCG
}
}
}
顶点/片元着色器是写在 Pass 语义块内的,而非 SubShader 内的.原因是:我们需要自己定义每个 Pass 需要使用的 Shader 代码.
3.4.3 被抛弃的角落:固定函数着色器
01.不支持可编程管线着色器,需要使用固定函数着色器(F