【Unity Shaders】學習筆記——SurfaceShader(六)混合紋理


【Unity Shaders】學習筆記——SurfaceShader(六)混合紋理


轉載請注明出處:http://www.cnblogs.com/-867259206/p/5619810.html

寫作本系列文章時使用的是Unity5.3。
寫代碼之前:

  1. 當然啦,如果Unity都沒安裝的話肯定不會來學Unity Shaders吧?

  2. 閱讀本系列文章之前你需要有一些編程的概念。

  3. 在VS里面,Unity Shaders是沒有語法高亮顯示和智能提示的,VS黨可以參考一下這篇文章使代碼高亮顯示,也可以下載shaderlabvsNShader之類的插件使代碼高亮顯示。

  4. 這是針對小白的Unity Shaders的基礎知識,如果你已經有了基礎或者你是大神,那么這些文章不適合你。

  5. 由於作者水平的局限,文中或許會有謬誤之處,懇請指出。


紋理混合就是將幾張紋理重合在一起顯示。最常見的情形是地形紋理。混合紋理可以優化性能,這樣只要渲染一次混合后的紋理即可,而不必渲染多次。
接下來要介紹的就是如何混合紋理制作地形着色器:
先准備幾張貼圖:
img
img
img
img
這幾張就是要混合圖片。
我們還需要下面這張圖片,這張圖片就決定了圖片是如何混合的:

(可以先轉到后面看效果)
好了,上代碼(我還是直接貼全部吧):

Shader "Custom/Textures" {
    Properties {  
        _MainTint ("Diffuse Tint", Color) = (1,1,1,1)  
          
        //Add the properties below so we can input all of our textures 
        _ColorA ("Terrain Color A", Color) = (1,1,1,1)  
        _ColorB ("Terrain Color B", Color) = (1,1,1,1)  
        _RTexture ("Red Channel Texture", 2D) = ""{}  
        _GTexture ("Green Channel Texture", 2D) = ""{}  
        _BTexture ("Blue Channel Texture", 2D) = ""{}  
        _ATexture ("Alpha Channel Texture", 2D) = ""{}  
        _BlendTex ("Blend Texture", 2D) = ""{}  
    }  
    SubShader {  
        Tags { "RenderType"="Opaque" }  
        LOD 200  
          
        CGPROGRAM  
        #pragma surface surf Lambert  
        // Important!
        #pragma target 4.0
  
        float4 _MainTint;  
        float4 _ColorA;  
        float4 _ColorB;  
        sampler2D _RTexture;  
        sampler2D _GTexture;  
        sampler2D _BTexture;  
        sampler2D _ATexture;  
        sampler2D _BlendTex;  
  
        struct Input {  
            float2 uv_RTexture;
            float2 uv_GTexture;  
            float2 uv_BTexture;  
            float2 uv_ATexture;  
            float2 uv_BlendTex;  
        };  
  
        void surf (Input IN, inout SurfaceOutput o) {  
            //Get the pixel data from the blend texture 
            //we need a float 4 here because the texture 
            //will return R,G,B,and A or X,Y,Z, and W 
            float4 blendData = tex2D(_BlendTex, IN.uv_BlendTex);  
              
            //Get the data from the textures we want to blend 
            float4 rTexData = tex2D(_RTexture, IN.uv_RTexture);  
            float4 gTexData = tex2D(_GTexture, IN.uv_GTexture);  
            float4 bTexData = tex2D(_BTexture, IN.uv_BTexture);  
            float4 aTexData = tex2D(_ATexture, IN.uv_ATexture);  
              
            //No we need to contruct a new RGBA value and add all 
            //the different blended texture back together 
            float4 finalColor;  
            finalColor = lerp(rTexData, gTexData, blendData.g);  
            finalColor = lerp(finalColor, bTexData, blendData.b);  
            finalColor = lerp(finalColor, aTexData, blendData.a);  
            finalColor.a = 1.0;  
              
            //Add on our terrain tinting colors 
            float4 terrainLayers = lerp(_ColorA, _ColorB, blendData.r);  
            finalColor *= terrainLayers;  
            finalColor = saturate(finalColor);  
                  
            o.Albedo = finalColor.rgb * _MainTint.rgb;  
            o.Alpha = finalColor.a;  
        }  
        ENDCG  
    }   
    FallBack "Diffuse"  
}  
  1. 注意我標注了Important!的那行代碼,我們在Input結構體里加入了5個UV坐標,如果沒寫#pragma target 4.0,在Input結構體里加入3個以上的UV坐標,會報錯Too many texture interpolators would be used for ForwardBase pass。要么就減少Input里面的UV坐標,那么就加上#pragma target 4.0。在這個例子中,幾張貼圖的紋理坐標是可以共用的,因為它們的Tilling和Offset的一樣,坐標是一樣的,也可以在后面的代碼中使用同一個坐標。不過如果想每張紋理都有自己的UV坐標以便受到更多的控制的話,那就設置目標編譯模型為4.0.(不過好像在4.X的版本里加入多個UV坐標不會報錯)

  2. 默認你已經看過了前面的文章了,所以大部分代碼不需要解釋。需要解釋的就是lerp函數。lerp就是線性插值。lerp(a,b,f)返回(1-f)*a+b*f。當f為1的時候,就是b值,當f為0時,就是a值,當f為0.5時,就是0.5a+0.5b,也就是f的值越大,a、b混合的值中b的值越大。

  3. 明白了lerp函數,顏色混合的那幾行代碼也就很容易理解了。第一句就是將BlendTexture中的綠色通道當作f值,也就BlendTexture中越綠的地方,gTexture的值越多,表現就是gTexture紋理越明顯。剩下的也是同樣的道理。

效果

按下面的貼圖順序給紋理賦值:
img
效果是這樣的:

當然貼圖順序是可以更換的,那樣會得到不同的效果。
我們看到,在BlendTexture中發紅的區域,顯示的紅色通道貼圖的石子,發綠的區域顯示的是綠色通道的石子加泥土,發藍的區域則是藍色通道中的草地,一些帶透明的區域顯示的則是透明通道中貼圖顏色。


免責聲明!

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



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