Shader入門精要學習記錄1

渲染管線

每次看都會有新的理解 反覆看吧

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

計劃加深normalmap的渲染並結合光照

先寫出基本結構

Shader "Practice/NormalMap"
{
    Properties
    {

    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct a2v{
            };
            struct v2f{
            };

            v2f vert(a2v v)
            {
                v2f o;
                return o;
            }

            fixed4 frag(v2f v):SV_TARGET
            {
                return fixed4(1,1,1,1);
            }

            ENDCG
        }
    }
}

接下來讓完成基本的一個能使用顏色調節的功能

Shader "Practice/NormalMap"
{
    Properties
    {
        _MainColor("Main Color",COLOR)=(1,1,1,1)
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            fixed4 _MainColor;
            struct a2v{
               float4 pos:POSITION;
            };
            struct v2f{
               float4 worldPos:SV_POSITION;
            };

            v2f vert(a2v v)
            {
                v2f o;
                o.worldPos=UnityObjectToClipPos(v.pos);
                return o;
            }

            fixed4 frag(v2f v):SV_TARGET
            {
                return _MainColor;
            }

            ENDCG
        }
    }
}

POSITION和SV_POSITION都是CG/HLSL的語義,它的返回值是一個float4類型的變量, POSITION語義告訴untiy把模型的頂點座標填充到參數pos中,SV_POSITION告訴Unity頂點着色器的輸出是裁剪空間中的頂點座標,SV_TARGET 告訴渲染器把用戶的輸出顏色儲存到一個渲染目標,這裏將輸出到默認的幀緩存中。
POSITION:頂點在模型座標系下的位置
這裏寫圖片描述
SV_POSITION:頂點在投影空間下的位置,注意和輸入的模型座標系下的位置不同,這個字段必必須設置,這個座標轉換是頂點着色器的重要工作。在unity中定義爲:
這裏寫圖片描述

UnityObjectToClipPos函數 找下定義 UnityCG.cginc文件中沒有定義但有這些文件Include
這裏寫圖片描述 在UnityShaderUtilities.cginc 找到
這裏寫圖片描述
這裏寫圖片描述
網上搜索解釋一下 UNITY_MATRIX_M V P這幾個:

define UNITY_MATRIX_M unity_ObjectToWorld:這裏寫圖片描述

Unity Shader中各種空間及變換方法

在內置文件的定義這是幾個意思?
別名 定義 含義
UNITY_MATRIX_M unity_ObjectToWorld 模型變換矩陣
UNITY_MATRIX_V unity_MatrixV 視圖變換矩陣
UNITY_MATRIX_P glstate_matrix_projection 投影變換矩陣
UNITY_MATRIX_VP unity_MatrixVP 視圖投影變換矩陣
UNITY_MATRIX_MV mul(unity_MatrixV, unity_ObjectToWorld) 模型視圖變換
UNITY_MATRIX_MVP mul(unity_MatrixVP, unity_ObjectToWorld) 模型視圖投影變換

這裏寫圖片描述

這裏寫圖片描述

下面完成Diffuse部分 頂點渲染

Shader "Practice/NormalMap"
{
    Properties
    {
        _MainColor("Main Color",COLOR)=(1,1,1,1)
        _Diffuse("DiffuseColor",COLOR)=(1,1,1,1)
    }
    SubShader
    {
       Tags{"LightMode"="ForwardBase"}
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            fixed4 _MainColor;
            fixed4 _Diffuse;
            struct a2v{
               float4 pos:POSITION;
               float3 normal:NORMAL;
            };
            struct v2f{
               float4 worldPos:SV_POSITION;
               fixed4 finalCol:COLOR;
            };

            v2f vert(a2v v)
            {
                v2f o;
                o.worldPos=UnityObjectToClipPos(v.pos);
                fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);
                fixed3 worldNormal=normalize(mul(v.normal,unity_ObjectToWorld));
                //fixed3 worldNormal=normalize(mul(v.normal,UNITY_MATRIX_M));等價
                o.finalCol=_LightColor0*_MainColor*_Diffuse*(dot(worldNormal,worldLightDir)*0.5f+0.5f);
                return o;
            }

            fixed4 frag(v2f v):SV_TARGET
            {
                fixed4 ambient=UNITY_LIGHTMODEL_AMBIENT;

                return v.finalCol+ambient;
            }

            ENDCG
        }
    }
}

如下是逐片元

Shader "Practice/NormalMap"
{
    Properties
    {
        _MainColor("Main Color",COLOR)=(1,1,1,1)
        _Diffuse("DiffuseColor",COLOR)=(1,1,1,1)
    }
    SubShader
    {
       Tags{"LightMode"="ForwardBase"}
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            fixed4 _MainColor;
            fixed4 _Diffuse;
            struct a2v{
               float4 pos:POSITION;
               float3 normal:NORMAL;
            };
            struct v2f{
               float4 worldPos:SV_POSITION;
               float3 worldNormal:NORMAL0;
            };

            v2f vert(a2v v)
            {
                v2f o;
                o.worldPos=UnityObjectToClipPos(v.pos);
                o.worldNormal=mul(v.normal,UNITY_MATRIX_M);
                return o;
            }

            fixed4 frag(v2f v):SV_TARGET
            {
                fixed4 ambient=UNITY_LIGHTMODEL_AMBIENT;
                fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);
                fixed3 worldNormal=normalize(v.worldNormal);
                fixed4 diffuse=_LightColor0*_MainColor*_Diffuse*(dot(worldNormal,worldLightDir)*0.5f+0.5f);
                return diffuse+ambient;
            }

            ENDCG
        }
    }
}

在上面的shader中可以嘗試輸出顏色瞭解各種值大概的大小和幫助理解。

下面實現高光

我擦 沒保存 重寫

由於這個相對來說容易忘記 記錄下
這裏寫圖片描述
這裏寫圖片描述

Shader "Practice/NormalMap"
{
    Properties
    {
      //  _MainTex("MainTex",2D)="white"{}
        _MainColor("Main Color",COLOR)=(1,1,1,1)
        _Diffuse("DiffuseColor",COLOR)=(1,1,1,1)
        _Specular("SpecuColor",COLOR)=(1,1,1,1)
        _Gloss("Gloss",Range(0,20))=8
    }
    SubShader
    {
       Tags{"LightMode"="ForwardBase"}
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            fixed4 _MainColor;
            fixed4 _Diffuse;
            fixed4 _Specular;
            float  _Gloss;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            struct a2v{
               float4 pos:POSITION;
               float3 normal:NORMAL;
               float2 uv:TEXCOORD;
            };
            struct v2f{
               float4 vertex:SV_POSITION;
               float3 worldNormal:NORMAL0;
               float3 worldPos:NORMAL1;
               float2 uv:TEXCOORD;
            };

            v2f vert(a2v v)
            {
                v2f o;
                o.vertex=UnityObjectToClipPos(v.pos);
                o.worldNormal=mul(v.normal,UNITY_MATRIX_M);
                o.worldPos=mul(v.pos,UNITY_MATRIX_M);
            //  o.uv=TRANSFORM_TEX(v.uv,_MainTex);
                return o;
            }

            fixed4 frag(v2f v):SV_TARGET
            {
             //   fixed4 texCol=tex2D(_MainTex,v.uv);
                fixed4 ambient=UNITY_LIGHTMODEL_AMBIENT;
                fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);
                fixed3 worldNormal=normalize(v.worldNormal);
                fixed4 diffuse=_LightColor0*_MainColor*_Diffuse*(dot(worldNormal,worldLightDir)*0.5f+0.5f);
                fixed3 viewDir=_WorldSpaceCameraPos.xyz-v.worldPos;     
                fixed3 refect=normalize(normalize(_WorldSpaceLightPos0.xyz)+normalize(viewDir));
                fixed4 specular=_Specular*_LightColor0* pow(saturate(dot(worldNormal,refect)),_Gloss);
                //return fixed4(viewDir,1);
                 return specular+diffuse+ambient;
            }

            ENDCG
        }
    }
}

接着實現簡單紋理

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

Shader "Practice/NormalMap"
{
    Properties
    {
        _MainTex("MainTex",2D)="white"{}
        _MainColor("Main Color",COLOR)=(1,1,1,1)
        _Diffuse("DiffuseColor",COLOR)=(1,1,1,1)
        _Specular("SpecuColor",COLOR)=(1,1,1,1)
        _Gloss("Gloss",Range(0,20))=8
    }
    SubShader
    {
       Tags{"LightMode"="ForwardBase"}
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            fixed4 _MainColor;
            fixed4 _Diffuse;
            fixed4 _Specular;
            float  _Gloss;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            struct a2v{
               float4 pos:POSITION;
               float3 normal:NORMAL;
               float2 uv:TEXCOORD;
            };
            struct v2f{
               float4 vertex:SV_POSITION;
               float3 worldNormal:NORMAL0;
               float3 worldPos:NORMAL1;
               float2 uv:TEXCOORD;
            };

            v2f vert(a2v v)
            {
                v2f o;
                o.vertex=UnityObjectToClipPos(v.pos);
                o.worldNormal=mul(v.normal,UNITY_MATRIX_M);
                o.worldPos=mul(v.pos,UNITY_MATRIX_M);
                o.uv=TRANSFORM_TEX(v.uv,_MainTex);
                return o;
            }

            fixed4 frag(v2f v):SV_TARGET
            {
                fixed4 texCol=tex2D(_MainTex,v.uv);
                fixed4 ambient=UNITY_LIGHTMODEL_AMBIENT;
                fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);
                fixed3 worldNormal=normalize(v.worldNormal);
                fixed4 diffuse=texCol*_LightColor0*_MainColor*_Diffuse*(dot(worldNormal,worldLightDir)*0.5f+0.5f);
                fixed3 viewDir=_WorldSpaceCameraPos.xyz-v.worldPos;     
                fixed3 refect=normalize(normalize(_WorldSpaceLightPos0.xyz)+normalize(viewDir));
                fixed4 specular=_Specular*_LightColor0* pow(saturate(dot(worldNormal,refect)),_Gloss);
                //return fixed4(viewDir,1);
                 return specular+diffuse+ambient;
            }

            ENDCG
        }
    }
}

爲什麼要定義 float4 _MainTex_ST ? TRANSFORM_TEX函數? tex2D函數?
這裏寫圖片描述
tex2D: 紋理採樣 CG標準函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章