Unity3D Shader 入門之簡單案例的實現(通過法線實現顏色變化)


在沒有接觸Unity3D  Shader 之前,總感覺shader特別神奇,因為聽說是對渲染流水線進行編程,就是對GPU進行編程。聽着特別高大上。這不,最近剛剛接觸Shader,學了幾個小案例,然后本文作為學習筆記將這個小案例的實現記錄下來。

筆者也是剛開始學習shader 沒幾天。在剛開始學shader 的時候,剛覺shader好難,面對shader一些奇怪的語法和一些語義,有點讓人頭疼。學着感覺一頭霧水,因為在學一些小案例之前還需要學習(復習)一些數學知識,因為涉及到坐標空間的轉換,所以看了很多矩陣運算和其他的一些數學知識。

我想很多學shader的人和我一樣吧,剛開始接觸shader的時候,發覺好難,我覺是因為沒有實現過一些小案例,所以讓shader披上了一層神秘的面紗。等實現了一些小案例就會發現,原來這東東是這樣玩的···

接下來我們就來實現一個小案例,效果如下圖:

 

然后來看看實現這種效果的過程

1.首先我們先建立一個測試項目,然后創建一個material(材質) 和 shader  ,在場景中創建一個球體和膠囊體。

2.把創建的shader賦給材質:

3.接下來就打開編輯器對shader進行編輯。

在此之前我們先來簡單了解以下shader框架

Shader "Custom/myshader"{
    Properties
    {
              // 屬性
    }
    Subshader
    {
              // 用於實現效果
    }
}
        

簡單了解過后,我們在Properties區域添加我們所需要的屬性

    Properties
    {
        _Color("Base Color",color)=(1,1,1,1)
        _MainTex("Base(RGB)",2D) = "white"{}
    }

屬性將會顯示在材質的屬性面板上,我們就可以通過面板對上面兩個屬性進行值的變換。為了讓美術和程序員合作,在shader中屬性的定義就是作為一個接口,程序員定義這個接口讓美術來調節渲染效果。

然后來看shader的核心部分,Subshader

Subshader
    {
     Tags{"Queue" = "transparent"  "RenderType" = "transparent"  "IgoreProjector" = "true" }     // 定義渲染所需要的一些標簽,讀者可以去查閱其他資料進行了解,在此不再累述
     Blend  SrcAlpha  oneMinusSrcAlpha     // 混合
     pass          // 渲染通道   注:一個Subshader里可以有多個pass
     {
        CGPROGRAM                 // 開始CG代碼
        #pragma vertex vert       // 重點,對頂點vert函數進行聲明 
        #pragma fragment frag     // 對片元frag函數進行聲明
        #include "UnityCG.cginc"  // 引入需要的文件(就像C++語言里的include一樣)

        sampler2D _MainTex;  // 變量名稱要和properties中的變量名稱相同,這個變量就有值了。
        float4 _Color;       // 同上

        struct v2f        // 結構體的定義是為了 vert  到   frag  的過度
        {
            float4 pos : POSITION;
            float4 uv   : TEXCOORD;
            float4 col :COLOR;
        };
        v2f vert(appdata_base v)    // appdata_base 來自於UnityCG.cginc    
        {
            v2f  o;
            o.pos = UnityObjectToClipPos(v.vertex);   // 坐標空間的轉換
            o.uv = v.texcoord;
            o.col.xyz = v.normal*0.5+0.5;   // 法線的取值范圍是-1到1   所以先乘0.5讓范圍到-0.5到0.5  ,在加上0.5,就符合顏色的取值范圍了。
            o.col.w = 1.0;
            return o;
        }
        half4 frag(v2f i) :COLOR 
        {
            half4 h = i.col;     // 賦值顏色
            return h;
        }
        ENDCG         // 結束CG代碼
     }

寫的很簡要,不過對於對shader有一小點了解的讀者來說可以理解了。

以下是完整源碼:

Shader "Custom/myshader"{
    Properties
    {
        _Color("Base Color",color)=(1,1,1,1)
        _MainTex("Base(RGB)",2D) = "white"{}
    }
    Subshader
    {
     Tags{"Queue" = "transparent"  "RenderType" = "transparent"  "IgoreProjector" = "true" }
     Blend  SrcAlpha  oneMinusSrcAlpha     
     pass 
     {
        Cull off
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #include "UnityCG.cginc"

        sampler2D _MainTex;
        float4 _Color;

        struct v2f
        {
            float4 pos : POSITION;
            float4 uv   : TEXCOORD;
            float4 col :COLOR;
        };
        v2f vert(appdata_base v)
        {
            v2f  o;
            o.pos = UnityObjectToClipPos(v.vertex);
            o.uv = v.texcoord;
            o.col.xyz = v.normal*0.5+0.5;   
            o.col.w = 1.0;
            return o;
        }
        half4 frag(v2f i) :COLOR 
        {
            half4 h = i.col;
            return h;
        }
        ENDCG
     }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM