为顶点程序传递顶点信息
Cg / HLSL顶点程序,顶点信息必须通过结构体传递。几个常用的顶点结构被定义在了UnityCG.cginc 文件中。而且在大多数情况下使用它们就足够了。
- appdata_base:顶点的位置,法线和一个纹理坐标。
- appdata_tan:顶点的位置,切线,法线和一个纹理坐标。
- appdata_full:顶点的位置,切线,法线,四个纹理坐标和颜色。
这个材质颜色的网格基于法线和只使用appdata_base顶点程序输入:
Shader "VertexInputSimple" { SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct v2f { float4 pos : SV_POSITION; fixed4 color : COLOR; }; v2f vert (appdata_base v) { v2f o; o.pos = mul (UNITY_MATRIX_MVP, v.vertex); o.color.xyz = v.normal * 0.5 + 0.5; o.color.w = 1.0; return o; } fixed4 frag (v2f i) : SV_Target { return i.color; } ENDCG } } }
如果你想访问不同的顶点信息,你需要声明自己的顶点结构体,或者给顶点着色器添加输入参数。顶点信息被认为是Cg/HLSL的语义,必须遵循以下规则:
语义:
- POSITION : 顶点坐标,典型的float4.
- NORMAL:法线顶点,典型的float3.
- TEXCOORD0:是第一个UV坐标,典型的float2,float3
- TEXCOORD1~TEXCOORD3 是第二道第四个UV坐标
- TANGENT : 是切向量(用于法线映射),典型的float4
- COLOR :是一种每个顶点都具备的颜色,典型的float
可视化UV
下面的Shader例子使用顶点坐标和第一个顶点着色器输入纹理坐标,在结构appdata中定义。这对于调试网格上的UV坐标非常有用。UV坐标可视化为红色和绿色的颜色(rg),超过0~1的范围的坐标有附加的蓝色色彩的应用。
Shader "Debug/UV 1" { SubShader { Pass { Fog { Mode Off } CGPROGRAM #pragma vertex vert #pragma fragment frag // vertex input: position, UV struct appdata { float4 vertex : POSITION; float4 texcoord : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float4 uv : TEXCOORD0; }; v2f vert (appdata v) { v2f o; o.pos = mul( UNITY_MATRIX_MVP, v.vertex ); o.uv = float4( v.texcoord.xy, 0, 0 ); return o; } half4 frag( v2f i ) : SV_Target { half4 c = frac( i.uv ); if (any(saturate(i.uv) - i.uv)) c.b = 0.5; return c; } ENDCG } } }
可视化顶点颜色
这个Shader使用顶点位置和种每个顶点都具备的颜色作为顶点着色器输入(在结构appdata定义)。
Shader "Debug/Vertex color" { SubShader { Pass { Fog { Mode Off } CGPROGRAM #pragma vertex vert #pragma fragment frag // vertex input: position, color struct appdata { float4 vertex : POSITION; fixed4 color : COLOR; }; struct v2f { float4 pos : SV_POSITION; fixed4 color : COLOR; }; v2f vert (appdata v) { v2f o; o.pos = mul( UNITY_MATRIX_MVP, v.vertex ); o.color = fixed4(1,0.8,0.7,1); return o; } fixed4 frag (v2f i) : SV_Target { return i.color; } ENDCG } } }
调试颜色材质应用到一个模型照明进颜色
可视化法线
使用顶点位置和法线作为顶点着色器输入(在结构appdata定义)。正常的X,Y,Z组件可视化为R,G,B的颜色。因为法线的值在1 . .1范围内,
Shader "Debug/Normals" { SubShader { Pass { Fog { Mode Off } CGPROGRAM #pragma vertex vert #pragma fragment frag // vertex input: position, normal struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; }; struct v2f { float4 pos : SV_POSITION; fixed4 color : COLOR; }; v2f vert (appdata v) { v2f o; o.pos = mul( UNITY_MATRIX_MVP, v.vertex ); o.color.xyz = v.normal * 0.5 + 0.5; o.color.w = 1.0; return o; } fixed4 frag (v2f i) : SV_Target { return i.color; } ENDCG } } }
调试法线材质应用到一个模型。您可以看到模型硬阴影边缘。
(忽略后面不明物体..............NGUI的模型)
可视化切线和副法线
切线和副法线向量用于法线贴图。在统一只有切向量存储在顶点,和副法线来源于法线和切线。
使用顶点位置和法线作为顶点着色器输入(在结构appdata定义)。切线的X,Y,Z组件可视化为R,G,B的颜色。
切线
Shader "Debug/Tangents" { SubShader { Pass { Fog { Mode Off } CGPROGRAM #pragma vertex vert #pragma fragment frag // vertex input: position, tangent struct appdata { float4 vertex : POSITION; float4 tangent : TANGENT; }; struct v2f { float4 pos : SV_POSITION; fixed4 color : COLOR; }; v2f vert (appdata v) { v2f o; o.pos = mul( UNITY_MATRIX_MVP, v.vertex ); o.color = v.tangent * 0.5 + 0.5; return o; } fixed4 frag (v2f i) : SV_Target { return i.color; } ENDCG } } }
(忽略前面不明物体................NGUI的模型)
副法线
它使用顶点位置,法线和切线顶点输入。从法线和切线计算副法线。像正常的法线或者切线。
Shader "Debug/Binormals" { SubShader { Pass { Fog { Mode Off } CGPROGRAM #pragma vertex vert #pragma fragment frag // vertex input: position, normal, tangent struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; float4 tangent : TANGENT; }; struct v2f { float4 pos : SV_POSITION; float4 color : COLOR; }; v2f vert (appdata v) { v2f o; o.pos = mul( UNITY_MATRIX_MVP, v.vertex ); // calculate binormal float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w; o.color.xyz = binormal * 0.5 + 0.5; o.color.w = 1.0; return o; } fixed4 frag (v2f i) : SV_Target { return i.color; } ENDCG } } }
时间: 2024-11-10 01:21:49