为顶点程序提供顶点数据

为顶点程序传递顶点信息

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
    }
}
}

posted @ 2015-12-04 14:09  我爱吃橙子  阅读(575)  评论(0编辑  收藏  举报