1. 程式人生 > >關於UnityShader的入門學習 (二)

關於UnityShader的入門學習 (二)

dba 反射 每一個 向量量化 ack 函數 gin clu tco

1.逐頂點的漫反射Shader

Shader "Mocha/04 Diffuse Vertex"{//逐頂點的漫反射
    
    Properties{
    
    _Diffuse("Diffuse Color",Color)=(1,1,1,1)
    }


    SubShader{
    
        Pass{
            //只有定義了正確的LightMode才能得到一些Unity的內置光照變量
            Tags{"LightMode"="ForwardBase"}

            CGPROGRAM
#include  "Lighting.cginc
" //取得第一個直射光的顏色_LightColor0 Unity內置 取得第一個直射光的位置 _WorldSpaceLightPos0 fixed3 _Diffuse; //頂點函數 這裏只是聲明了頂點函數的函數名 //基本作用 完成頂點坐標從模型空間到剪裁空間的轉換(從遊戲環境到相機視野屏幕上) #pragma vertex vert //片元函數 這裏只是聲明了片元函數的函數名 //基本作用 返回模型對應的屏幕上的每一個像素的顏色值 #pragma fragment frag //
使用結構體存儲 //a2v 即 application to vertex struct a2v{ float4 vertex:POSITION;//告訴Unity把模型空間下的頂點坐標填充給vertex float3 normal:NORMAL;//告訴Unity把模型空間下的法線方向填充給normal }; //使用結構體存儲 struct v2f{ float4 position:SV_POSITION;
//告訴Unity存儲剪裁空間下的頂點坐標 fixed3 color:COLOR;//存儲顏色語義 }; v2f vert(a2v v){ v2f f; f.position=mul(UNITY_MATRIX_MVP,v.vertex); //將模型空間坐標轉換到剪裁空間坐標 fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.rgb; //獲取到Unity環境光 fixed3 normalDir=normalize(mul(v.normal,(float3x3)_World2Object));//將模型空間轉換到世界空間,再將向量量化 //_World2Object 在左側世界空間轉模型空間,在右側模型空間轉世界空間 fixed3 lightDir=normalize(_WorldSpaceLightPos0.xyz);//對於每個頂點來說光的位置就是光的方向,因為光是平行光 fixed3 diffuse=_LightColor0.rgb*max(dot(normalDir,lightDir),0)*_Diffuse.rgb;//取得漫反射的顏色 f.color=diffuse + ambient; return f; } fixed4 frag(v2f f) : SV_Target{ return fixed4(f.color,1); } ENDCG } } Fallback "VertexLit" }

2.逐像素(片元)的漫反射Shader

Shader "Mocha/06 Diffuse Fragment HalfLambert"{//逐像素(片元)的半蘭伯特光照
    
    Properties{
    
    _Diffuse("Diffuse Color",Color)=(1,1,1,1)
    }


    SubShader{
    
        Pass{
            //只有定義了正確的LightMode才能得到一些Unity的內置光照變量
            Tags{"LightMode"="ForwardBase"}

            CGPROGRAM
#include  "Lighting.cginc"    //取得第一個直射光的顏色_LightColor0 Unity內置  取得第一個直射光的位置 _WorldSpaceLightPos0

            fixed3 _Diffuse;

            //頂點函數 這裏只是聲明了頂點函數的函數名
            //基本作用 完成頂點坐標從模型空間到剪裁空間的轉換(從遊戲環境到相機視野屏幕上)
#pragma vertex vert
            //片元函數 這裏只是聲明了片元函數的函數名
            //基本作用 返回模型對應的屏幕上的每一個像素的顏色值
#pragma fragment frag
            
            //使用結構體存儲
            //a2v 即 application to vertex
            struct a2v{ 
                float4 vertex:POSITION;//告訴Unity把模型空間下的頂點坐標填充給vertex
                float3 normal:NORMAL;//告訴Unity把模型空間下的法線方向填充給normal
            };

            //使用結構體存儲
            struct v2f{
                float4 position:SV_POSITION;//告訴Unity存儲剪裁空間下的頂點坐標
                fixed3 wordNormalDir:COLOR;//存儲顏色語義
            };

            v2f vert(a2v v){
                v2f f;

                f.position=mul(UNITY_MATRIX_MVP,v.vertex); //將模型空間坐標轉換到剪裁空間坐標

                f.wordNormalDir=mul(v.normal,(float3x3)_World2Object);

                return f;
            }
            fixed4 frag(v2f f) : SV_Target{

                fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.rgb;    //獲取到Unity環境光

                fixed3 normalDir=normalize(f.wordNormalDir);//將模型空間轉換到世界空間,再將向量量化

                //_World2Object 在左側世界空間轉模型空間,在右側模型空間轉世界空間

                fixed3 lightDir=normalize(_WorldSpaceLightPos0.xyz);//對於每個頂點來說光的位置就是光的方向,因為光是平行光

                float halfLambert=dot(normalDir,lightDir)*0.5+0.5;    //半蘭伯特光照算法

                fixed3 diffuse=_LightColor0.rgb*halfLambert*_Diffuse.rgb;//取得漫反射的顏色

                fixed3 tempColor=diffuse + ambient;

                return fixed4(tempColor,1);
            }


            ENDCG
        }
    
    }
    Fallback "VertexLit"

}

3.逐頂點的高光反射Shader

Shader "Mocha/07 Specular Vertex"{//逐頂點的高光反射
    
    Properties{
    
    _Diffuse("Diffuse Color",Color)=(1,1,1,1)  //材質顏色
    _Specular("Specular Color",Color)=(1,1,1,1)//高光顏色
    _Gloss("Gloss",Range(8,200))=10               //高光參數
    }


    SubShader{
    
        Pass{
            //只有定義了正確的LightMode才能得到一些Unity的內置光照變量
            Tags{"LightMode"="ForwardBase"}

            CGPROGRAM
#include  "Lighting.cginc"    //取得第一個直射光的顏色_LightColor0 Unity內置  取得第一個直射光的位置 _WorldSpaceLightPos0

            fixed3 _Diffuse;
            fixed4 _Specular;
            half _Gloss;

            //頂點函數 這裏只是聲明了頂點函數的函數名
            //基本作用 完成頂點坐標從模型空間到剪裁空間的轉換(從遊戲環境到相機視野屏幕上)
#pragma vertex vert
            //片元函數 這裏只是聲明了片元函數的函數名
            //基本作用 返回模型對應的屏幕上的每一個像素的顏色值
#pragma fragment frag
            
            //使用結構體存儲
            //a2v 即 application to vertex
            struct a2v{ 
                float4 vertex:POSITION;//告訴Unity把模型空間下的頂點坐標填充給vertex
                float3 normal:NORMAL;//告訴Unity把模型空間下的法線方向填充給normal
            };

            //使用結構體存儲
            struct v2f{
                float4 position:SV_POSITION;//告訴Unity存儲剪裁空間下的頂點坐標
                fixed3 color:COLOR;//存儲顏色語義
            };

            v2f vert(a2v v){
                v2f f;

                f.position=mul(UNITY_MATRIX_MVP,v.vertex); //將模型空間坐標轉換到剪裁空間坐標

                fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.rgb;    //獲取到Unity環境光

                fixed3 normalDir=normalize(mul(v.normal,(float3x3)_World2Object));//將模型空間轉換到世界空間,再將向量量化

                //_World2Object 在左側世界空間轉模型空間,在右側模型空間轉世界空間

                fixed3 lightDir=normalize(_WorldSpaceLightPos0.xyz);//對於每個頂點來說光的位置就是光的方向,因為光是平行光

                fixed3 diffuse=_LightColor0.rgb*max(dot(normalDir,lightDir),0)*_Diffuse.rgb;//取得漫反射的顏色

                fixed3 reflectDir=normalize(reflect(-lightDir,normalDir));//獲取到發射光的單位向量

                fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-mul(v.vertex,_World2Object).xyz);//獲取到相機視角方向單位向量

                fixed3 specular=_LightColor0.rgb*_Specular*pow(max(dot(reflectDir,viewDir),0),_Gloss);//計算的到高光顏色(其中_Gloss為高光參數 根據效果需要更改數值 一般取大於10的數值)

                f.color=diffuse + ambient+specular;

                return f;
            }
            fixed4 frag(v2f f) : SV_Target{

                return fixed4(f.color,1);
            }


            ENDCG
        }
    
    }
    Fallback "VertexLit"

}

4.逐像素(片元)的高光反射Shader

Shader "Mocha/08 Specular Fragment"{//逐像素(片元)的高光反射
    
    Properties{
    
    _Diffuse("Diffuse Color",Color)=(1,1,1,1)  //材質顏色
    _Specular("Specular Color",Color)=(1,1,1,1)//高光顏色
    _Gloss("Gloss",Range(8,200))=10               //高光參數
    }


    SubShader{
    
        Pass{
            //只有定義了正確的LightMode才能得到一些Unity的內置光照變量
            Tags{"LightMode"="ForwardBase"}

            CGPROGRAM

#include  "Lighting.cginc"    //取得第一個直射光的顏色_LightColor0 Unity內置  取得第一個直射光的位置 _WorldSpaceLightPos0

            fixed3 _Diffuse;
            fixed4 _Specular;
            half _Gloss;

            //頂點函數 這裏只是聲明了頂點函數的函數名
            //基本作用 完成頂點坐標從模型空間到剪裁空間的轉換(從遊戲環境到相機視野屏幕上)
#pragma vertex vert
            //片元函數 這裏只是聲明了片元函數的函數名
            //基本作用 返回模型對應的屏幕上的每一個像素的顏色值
#pragma fragment frag
            
            //使用結構體存儲
            //a2v 即 application to vertex
            struct a2v{ 
                float4 vertex:POSITION;//告訴Unity把模型空間下的頂點坐標填充給vertex
                float3 normal:NORMAL;//告訴Unity把模型空間下的法線方向填充給normal
            };

            //使用結構體存儲
            struct v2f{
                float4 position:SV_POSITION;//告訴Unity存儲剪裁空間下的頂點坐標
                float3 worldNormal:TEXCOORD0;//紋理語義存儲
                float3 worldVertex:TEXCOORD1;//紋理語義存儲
            };
            v2f vert(a2v v){
                v2f f;

                f.position=mul(UNITY_MATRIX_MVP,v.vertex); //將模型空間坐標轉換到剪裁空間坐標
                f.worldNormal=mul(v.normal,(float3x3)_World2Object);
                f.worldVertex=mul(v.vertex,_World2Object).xyz;
                return f;
            }
            fixed4 frag(v2f f) : SV_Target{

                fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.rgb;    //獲取到Unity環境光

                fixed3 normalDir=normalize(f.worldNormal);//將模型空間轉換到世界空間,再將向量量化

                //_World2Object 在左側世界空間轉模型空間,在右側模型空間轉世界空間

                fixed3 lightDir=normalize(_WorldSpaceLightPos0.xyz);//對於每個頂點來說光的位置就是光的方向,因為光是平行光

                fixed3 diffuse=_LightColor0.rgb*max(dot(normalDir,lightDir),0)*_Diffuse.rgb;//取得漫反射的顏色

                fixed3 reflectDir=normalize(reflect(-lightDir,normalDir));//獲取到發射光的單位向量

                fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-f.worldVertex);//獲取到相機視角方向單位向量

                fixed3 specular=_LightColor0.rgb*_Specular*pow(max(dot(reflectDir,viewDir),0),_Gloss);//計算的到高光顏色(其中_Gloss為高光參數 根據效果需要更改數值 一般取大於10的數值)

                fixed3 tempColor=diffuse + ambient+specular;

                return fixed4(tempColor,1);
            }


            ENDCG
        }
    
    }
    Fallback "VertexLit"

}

關於UnityShader的入門學習 (二)