Unity3D - Shader - 顶点/片段着色器的基本结构

基本结构

Shader "MyShaderName" {
    Properties {
        // 属性
    }

    SubShader {
        // 针对显卡A的SubShader
        Pass {
            // 设置渲染状态和标签

            // 开始CG代码片段
            CGPROGRAM

            // 该段代码片段的编译指令,例如:
            #pragma vertex vert
            #pragma fragment frag

            // CG代码写在这里

            ENDCG

            // 其他设置
        }

        // 其他需要的Pass
    }

    SubShader {
        // 针对显卡B的SubShader
    }

    // 上述SubShader都失败后用于回调的Unity Shader
    Fallback "VertexLit"
}

白色Shader

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unity Shaders Book/Chapter 5/Simple Shader" {
    SubShader {
        Pass {
            CGPROGRAM

            // 两个重点的编译指令
            // 更通用的表示, name是指定的函数名:
            // #pragma vertex name
            // #pragma fragment name
            #pragma vertex vert         // 告诉Unity哪个函数包含了顶点着色器代码
            #pragma fragment frag       // 告诉Unity哪个函数包含了片元着色器

            // POSITION和SV_POSITION都是Cg/HLSL中的语义
            // POSITION 告诉Unity把模型的顶点坐标填充到输入参数v中
            // SV_POSITION 告诉Unity顶点着色器的输出是裁剪空间中的顶点坐标
            float4 vert(float4 v : POSITION) : SV_POSITION {
                // 把顶点坐标从模型空间转换到裁剪空间中
                // UNITY_MATRIX_MVP矩阵是Unity内置的模型*观察*投影矩阵
                // mul(UNITY_MATRIX_MVP,*)
                return UnityObjectToClipPos(v);
            }

            // SV_Target是HLSL的一个系统语义,
            // 把用户的输出颜色存储到一个渲染目标(render target),
            // 这里输出到默认的帧缓冲中。
            // 片元着色器输出的颜色每个分量在[0,1],其中(0,0,0)表示黑色
            // (1,1,1)表示白色
            fixed4 frag() : SV_Target {
                return fixed4(1.0, 1.0, 1.0, 1.0);
            }

            ENDCG
        }
    }
}

传递更多数据

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unity Shaders Book/Chapter 5/Simple Shader1" {
    SubShader {
        Pass {
            CGPROGRAM

            #pragma vertex vert 
            #pragma fragment frag

            // 使用一个结构体来定义顶点着色器
            struct a2v {
                // POSITION 语义告诉 Unity,用模型空间的顶点坐标填充vertex变量
                float4 vertex : POSITION;
                // NORMAL语义告诉 Unity,用模型空间的法线方向填充normal变量
                float3 normal : NORMAL;
                // TEXCOORD0语义告诉Unity,用模型的第一套纹理坐标填充texcoord变量
                float4 texcoord : TEXCOORD0;
            };

            float4 vert(a2v v) : SV_POSITION {
                // 使用v.vertex来访问模型空间的顶点坐标
                return UnityObjectToClipPos(v.vertex);
            }

            fixed4 frag() : SV_Target {
                return fixed4(1.0, 1.0, 1.0, 1.0);
            }

            ENDCG
        }
    }
}

顶点着色器和片元着色器通信

Shader "Unity Shaders Book/Chapter 5/Simple Shader2" {
    SubShader {
        Pass {
            CGPROGRAM

            #pragma vertex vert 
            #pragma fragment frag

            struct a2v {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 texcoord : TEXCOORD0;
            };

            struct v2f {
                // SV_POSITION语义告诉Unity,pos里包含了顶点在裁剪空间
                // 中的位置信息
                float4 pos : SV_POSITION;
                // COLORO语义可以告诉用于存储颜色信息
                fixed3 color: COLOR0;
            };

            v2f vert(a2v v)  {
                // 声明输出结构
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                // v.normal 包含了顶点的法线方向,其分量范围在[-1.0, 1.0]
                // 下面的代码把分量范围映射到了[0.0, 1.0]
                // 存储到o.color中传递给片元着色器
                o.color = v.normal * 0.5 + fixed3(0.5, 0.5, 0.5);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target {
                // 将插值后的i.color显示到屏幕上
                return fixed4(i.color, 1.0);
            }

            ENDCG
        }
    }
}

ShaderLab中属性的类型和Cg中变量的类型之间的匹配关系:

ShaderLab属性类型 Cg变量类型
Color, Vector float4, half4, fixed4
Range, Float float, half, fixed
2D sampler2D
Cube samplerCube
3D sampler3D

float/half/fixed

Cg/HLSL中三种精度的数值类型:

类型 Cg/HLSL中3个精度的数值类型
float 最高精度的浮点值。通常使用32位来存储
half 中等精度的浮点值。通常使用16位来存储,范围精度是-60000 ~ +60000
fixed 最低精度的浮点值。通常使用11位来存储,经度范围是-2.0 ~ +2.0

可以使用fixed来存储颜色和单位矢量,如果要存储更大范围的数据可以选择half,最差的情况再选择float。

你可能感兴趣的:(Unity3D,Unity3D教程学习)