Unity Fragment Shader

The fragment shader receives the data from the vertex shader and calculates the color of the color pixel. When the value in the vertex shader is passed to the fragment shader, it will be interpolated once.

Let's look at some examples:

1. Fixed color


Shader "MyShader/VFShaderTest" {
    Properties
    {
        // 属性名 ("面板显示名称", 类型) = 默认值
        _MainColor ("显示颜色", Color) = (1, 0, 0, 1)
    }
 
    SubShader
    {
        Pass
        {
            CGPROGRAM // CG语言的开始
            // 编译指令 着色器名称 函数名称
            #pragma vertex vert // 顶点着色器, 每个顶点执行一次
            #pragma fragment frag // 片段着色器
            // 导入头文件
            #include "UnityCG.cginc"
 
            // 声明属性变量, 必须与外部属性变量名称一致
            fixed4 _MainColor;
 
            // 顶点着色器
            half4 vert(half4 vertexPos: POSITION): SV_POSITION
            {
                // 将局部坐标系下坐标转换为裁剪坐标系下坐标
                return UnityObjectToClipPos(vertexPos); 
            }
 
            // 片元着色器
            fixed4 frag(): COLOR
            {
                return _MainColor;
            }
 
            ENDCG // CG语言的结束
        }
    }
 
    FallBack "Diffuse"

2. Illumination

The main technical point, vector point multiplication to get a vector projection on another vector. That is, the closer the two vectors are to the vertical value, the smaller the value. Based on this judgment, the direct light surface is set to be the brightest. The first one is Lambert lighting, and the second is half Lambert lighting. Half Lambert lighting is to add 0.5 to the Lambert lighting to solve the problem of too dark back.

Shader "MyShader/VFShaderLight" {
    Properties
    {
        // 属性名 ("面板显示名称", 类型) = 默认值
        _DiffuseColor("漫反射颜色", Color) = (1, 0, 0, 1)
    }

    SubShader
    {
        Pass
        {
            Tags {"LightMode" = "ForwardBase"}
            CGPROGRAM // CG语言的开始
            // 编译指令 着色器名称 函数名称
            #pragma vertex vert // 顶点着色器, 每个顶点执行一次
            #pragma fragment frag // 片段着色器, 每个像素执行一次

            // 导入头文件
            #include "UnityCG.cginc"

            // 声明属性变量, 必须与外部属性变量名称一致
            fixed4 _DiffuseColor;

            struct appdata // 顶点着色器输入结构体
            {
                half4 vertexPos: POSITION; // 局部坐标系下顶点坐标
                half3 vertexNormal: NORMAL; // 局部坐标系下顶点法线向量
            };

            struct v2f // 顶点着色器输出结构体
            {
                half4 clipPos: SV_POSITION; // 裁剪坐标系下顶点坐标
                half3 worldNormal: Normal; // 裁剪坐标系下顶点法线向量
                half3 worldLightDir : TEXCOORD0; // 光照方向
            };

            // 顶点着色器
            v2f vert(appdata data)
            {
                v2f o;
                o.clipPos = UnityObjectToClipPos(data.vertexPos); // 等价于: mul(UNITY_MATRIX_MVP, data.vertexPos)
                o.worldNormal = UnityObjectToWorldNormal(data.vertexNormal); // 将局部坐标系下法线转换为世界坐标系下法线
                o.worldLightDir = UnityWorldSpaceLightDir(data.vertexPos); // 计算世界坐标系下顶点指向光源的向量
                return o;
            }

            // 片元着色器
            fixed4 frag(v2f input) : COLOR
            {
                //点乘得到一个向量在另一个向量投影。也就是两个向量越接近垂直值越小
                half factor = dot(input.worldNormal, input.worldLightDir); 
                //return _DiffuseColor * factor + UNITY_LIGHTMODEL_AMBIENT; // Lambert光照模型
                return _DiffuseColor * (0.5 * factor + 0.5) + UNITY_LIGHTMODEL_AMBIENT; // 半Lambert光照模型
            }
            ENDCG // CG语言的结束
        }
    }
    FallBack "Diffuse"
}

3. Textures

Shader "MyShader/VFShaderTexture" {
    Properties
    {
        // 属性名 ("面板显示名称", 类型) = 默认值
        _MainTex("2阶贴图", 2D) = "white" {}
    }

        SubShader
    {
        Pass
        {
            Tags {"LightMode" = "ForwardBase"}
            CGPROGRAM // CG语言的开始
            // 编译指令 着色器名称 函数名称
            #pragma vertex vert // 顶点着色器, 每个顶点执行一次
            #pragma fragment frag // 片段着色器, 每个像素执行一次

            // 导入头文件
            #include "UnityCG.cginc"

            // 声明属性变量, 必须与外部属性变量名称一致
            sampler2D _MainTex;

            struct appdata // 顶点着色器输入结构体
            {
                half4 vertexPos: POSITION; // 顶点坐标
                half2 uv_MainTex: TEXCOORD0; // 纹理uv坐标
            };

            struct v2f // 顶点着色器输出结构体
            {
                half4 clipPos: SV_POSITION; // 屏幕坐标
                half2 uv_MainTex: TEXCOORD0; // 纹理uv坐标
            };

            // 顶点着色器
            v2f vert(appdata data)
            {
                v2f o;
                o.clipPos = UnityObjectToClipPos(data.vertexPos); // 等价于: mul(UNITY_MATRIX_MVP, data.vertexPos)
                o.uv_MainTex = data.uv_MainTex;
                return o;
            }

            // 片元着色器
            fixed4 frag(v2f input) : COLOR
            {
                return tex2D(_MainTex, input.uv_MainTex);
            }

            ENDCG // CG语言的结束
        }
    }

        FallBack "Diffuse"
}

Project example download

Guess you like

Origin blog.csdn.net/st75033562/article/details/129307456