系统语义与函数体
系统语义标记,指该类型将返回给流水线GPU做处理。
结构体做返回值时,不需要在函数头标记系统语义。结构体外部和内部的标记会产生二义性,所以新版本只能在内部声明
原版错误
Shader "Unity Shaders Book/Chapter 5/Simple Shader" {Properties {// 声明一个Color类型的属性_Color ("Color Tint", Color) = (1.0,1.0,1.0,1.0)}SubShader {Pass {CGPROGRAM#pragma vertex vert#pragma fragment frag// 在Cg代码中,我们需要定义一个与属性名称和类型都匹配的变量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) : SV_POSITION { // 错误,不能在外面声明,不再可以自动解构v2f o;o.pos = mul(UNITY_MATRIX_MVP, 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;// 使用_Color属性来控制输出颜色c *= _Color.rgb;return fixed4(c, 1.0);}ENDCG}}
}
- 不再容忍模糊或错误的语义使用
- 不允许给结构体整体标记语义(如 struct v2f : SV_POSITION)
mul 被遗弃,会自动转换为UnityObjectToClipPos
改正后
Shader "Unity Shaders Book/Chapter 5/Simple Shader" {Properties {// 声明一个Color类型的属性_Color ("Color Tint", Color) = (1.0,1.0,1.0,1.0)}SubShader {Pass {CGPROGRAM#pragma vertex vert#pragma fragment frag// 在Cg代码中,我们需要定义一个与属性名称和类型都匹配的变量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;// 使用_Color属性来控制输出颜色c *= _Color.rgb;return fixed4(c, 1.0);}ENDCG}}
}
传入的结构体系统语义会被GPU捕捉赋值,返回的结构体的系统语义会被自动解构获取
也就是说,两种函数头
结构体内部标记系统语义,函数头不再声明
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;// 使用_Color属性来控制输出颜色c *= _Color.rgb;return fixed4(c, 1.0);
}