基本结构
代码
Shader "ShaderBook/Chapter5/Simpleshader"
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float4 vert (float4 v:POSITION):SV_POSITION
{
return UnityObjectToClipPos(v);
}
fixed4 frag () : SV_Target
{
return fixed4(1.0,1.0,1.0,1.0);
}
ENDCG
}
}
}
解释
1.Shader " "{ }:
- 代表一个shader。
- 字符串代表shader在unity面板中的路径。
2.SubShader{ }:
- 代表一个子Shader。
- 一个Shader可以包含多个子Shader。
3.Pass{ }:
- 代表一个Pass,一次渲染。
- 子Shader中可以包含多个Pass。
4.CGPROGRAM和ENDCG:
- 代表其中包含的代码是cg语法。
5.#pragma vertex name:
- 指定顶点函数的名称,使得unity可以调用。
- frag也一样,指定片元函数的名称。
6.vert函数:
- 渲染每个顶点都会调用一次此函数。接收来自模型空间的信息,返回裁剪空间的信息(传递给片元函数)。最基本的操作是把顶点从模型空间转换到裁剪空间。接收顶点信息的方式是定义变量并指定变量的语义。
- 顶点的位置信息是四元变量,每个值的范围都比较大,所以用float4表示。接收模型信息的语义是POSITION。裁剪空间的位置对应的语义是SV_POSITION。
- 指定语义的具体方式就是在变量后加:。返回值在函数的括号后加:。
7.frag函数:
- 渲染每个片元时都会被调用一次。接收来自vert函数的信息,返回输出到缓存,用于把颜色显示在屏幕上。
- 返回值类型是一个四元的颜色,颜色的分量值在0-1之间,所以用fixed4。返回的缓存代表的语义是SV_Target。
常用写法
代码
Shader "ShaderBook/Chapter5/Simpleshader"
{
Properties
{
_Color("Color Tint",Color)=(1.0,1.0,1.0,1.0)
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
fixed4 _Color;
struct a2v{
float4 vertex:POSITION;
float3 normal:NORMAL;
float4 texcoord:TEXCOORD0;
};
struct v2f{
float4 pos:SV_POSITION;
fixed3 color:COLOR0;
};
v2f vert (a2v v)
{
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);
o.color=v.normal*0.5+fixed3(0.5,0.5,0.5);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 c=i.color;
c*=_Color.rgb;
return fixed4(c,1.0);
}
ENDCG
}
}
}
解释
1.Properties{ }:
- 定义shader暴露在Material面板上可以控制的变量。
- 语法是:变量名(“面板上的变量名称”,变量类型) = 变量默认值
- 变量类型有:Color、Vector、Range、Float、2D、3D、Cube。
2.fixed4 _Color:
- 暴露在面板上的变量和cg代码中的变量同名时就可以通过外部来控制内部变量的值了。所以在cg代码中定义一个同名变量。cg代码中的变量类型和面板上的变量类型有些不同。
- 变量对应关系为:(1)Color,Vector对应float4,half4,fixed4。(2)Range,Float对应float,half,fixed。(3)2D对应sampler2D,3D对应sampler3D,Cube对应samplerCube。
3.vert函数获取多个变量,返回多个变量,用结构体包装
(1)a2v:(application to vertex)
- float4 vertex:POSITION; 位置是个点,用4个分量表示。
- float3 normal:NORMAL; 法线是向量,用3个分量表示。
- float4 texcoord:TEXCOORD0; 纹理坐标有uv,还有scale和offset,用4个分量表示。
(2)v2f:(vertex to fragment)
- float4 pos:SV_POSITION; 返回的裁剪空间的位置。
- fixed3 color:COLOR0; 返回的顶点颜色,frag函数会用顶点颜色插值得到片元颜色。