頂點色的訪問


頂點函數是在每個頂點被傳送到GPU之前被調用一次。它的作用是從模型坐標系中得到三維坐標,然后再轉換到其渲染到屏幕時在屏幕坐標系中的二維位置。因此,通過頂點函數,我們可以修改頂點的位置、顏色和UV坐標。一旦我們完成了對頂點的修改后,就會進入到surf函數的執行。與頂點函數是逐頂點執行的方式不同,surf函數則是逐像素執行的。

通過頂點函數,我們可以創造像海上的波浪、旗幟飄動的動態效果,或者使用Shader來給頂點着色。這一篇,我們來學習如何在一個Surface Shader中創建一個最簡單的頂點函數!

 

 

首先,我們要准備一個已經給頂點着色過的模型,以便我們可以在頂點函數中查看頂點顏色。為了方便,我們使用本書自帶資源(見文章開頭)中第七章的模型資源——VertexColorObject.fbx。我們把VertexColorObject.fbx導入Unity,並拖入到一個新的場景中。最后添加一個平行光。

 

新建一個Shader和Material,可以分別命名為SimpleVertexColor,並將Shader賦給Material,再將Material賦給模型。

 

       你的場景應該看起來是這樣的:

 

下面,我們開始編寫Shader。

在Properties塊中添加新的Properties:

 

Properties 
{

     _MainTint(“Global Color Tint”, Color) = (1,1,1,1)
}

 

為Properties中新添加的屬性添加對應的引用:
float4 _MainTint;

下面是很重要的Input結構。我們添加了一個新的變量vertColor以便surf函數可以訪問vert函數中傳遞的數據:

 

struct Input 
{
      float2 uv_MainTex;
      float4 vertColor;
};

 

最后,我們使用從Input中得到的數據填充SurfaceOutput結構體的Albedo參數:

void surf (Input IN, inout SurfaceOutput o) 
{
    o.Albedo = IN.vertColor.rgb * _MainTint.rgb;
}

完整代碼如下:

Shader “Custom/SimpleVertexColor” {
Properties 
{
       _MainTint(“Global Color Tint”, Color) = (1,1,1,1)
}

SubShader 
{

      Tags { “RenderType”=”Opaque” }
      LOD 200


      CGPROGRAM
      #pragma surface surf Lambert vertex:vert
      float4 _MainTint;

      struct Input 
      {
              float2 uv_MainTex;
              float4 vertColor;
      };

      void vert(inout appdata_full v, out Input o)
      {
            o.vertColor = v.color;
       }

      void surf (Input IN, inout SurfaceOutput o) 
     {
           o.Albedo = IN.vertColor.rgb * _MainTint.rgb;
      }

      ENDCG
} 

FallBack “Diffuse”

}

效果如下:

解釋

通過頂點函數,我們可以修改頂點的位置、顏色、UV坐標等值。在本節中我們使用了一個從maya導入的已給頂點着色的模型,但我們可以發現,在使用默認材質的情況下這些顏色在Unity中是不顯示的。我們需要編寫Shader,提取這些顏色再在模型上顯示出來。

我們首先通過在#pragma聲明中添加vertex:vert語句。這實際上告訴Unity,嘿,不要用你自己內置的頂點函數訪問模型頂點信息啦,去我寫的Shader里找一個名叫vert的家伙,用它去處理信息!如果Unity沒有找到,它就會報一個編譯錯誤。

vert函數里,除了我們熟悉的Input結構體,還有一個很特別的參數——appdata_full 。這個參數也是Unity內置的一個變量,它包含了模型頂點的所有信息,包括位置、切線、法線、兩個紋理坐標和顏色信息。其他的還有appdata_base和appdata_tan,具體可以看見官網。

你還可以發現,vertColor是一個float4類型的變量,這意味着我們還可以訪問它的透明通道。像下面這樣:

void surf (Input IN, inout SurfaceOutput o) 

{

      o.Albedo = IN.vertColor.rgb * _MainTint.rgb;

      o.Alpha = IN.vertColor.a;

}

 


免責聲明!

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



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