Unity3D ShaderLab压缩混合纹理贴图

 

纹理可以用于存储大量的数据,我们可以把多个图像打包存储在单一的RGBA纹理上,然后通过着色器代码提取这些元素,

我们就可以使用每个图片的RGBA通道的讯息作为一个独立的纹理。

这种使用场景特别是在地面的混合着色上有着很明显的优势,下面我们就来说说 怎么构建一个常用的四纹理混合着色器。

那么请县创建一个shader和材质球吧。下面我们直接开始:

1,修改Properties

{

//设置GUI;

_MainTint("Diffuse Tint",Color)=(1,1,1,1)

_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)=""

_BlendTexture("Blend Texture",2D)=""

}

 

2SubShader申明变量

#pragma surface surf Lambert

//变量;

float4 _MainTint;

float4 _ColorA;

float4 _ColorB;

sampler2D _RTexture;

sampler2D _GTexture;

sampler2D _BTexture;

sampler2D _ATexture;

sampler2D _BlendTexture;

 

3,修改Input结构

struct Input {

float2 uv_RTexture;

float2 uv_GTexture;

float2 uv_BTexture;

float2 uv_ATexture;

float2 uv_BlendTexture;

};

 

4,修改无敌的surf函数

void surf (Input IN, inout SurfaceOutput o) {

//得到纹理讯息;

float4 blendData = tex2D(_BlendTexture,IN.uv_BlendTexture);

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); 

//进行纹理混合;

float4 finalColor;

finalColor = lerp(rTexData,gTexData,blendData.g);

finalColor = lerp(finalColor,bTexData,blendData.b);

finalColor = lerp(finalColor,aTexData,blendData.a);

finalColor.a=1;

//计算色调;

float4 terrainLayers = lerp(_ColorA,_ColorB,blendData.r)*2;

finalColor *= terrainLayers;

finalColor = saturate(finalColor);

//half4 c = tex2D (_MainTex, IN.uv_MainTex);

o.Albedo = finalColor.rgb*_MainTint.rgb;

o.Alpha = finalColor.a;

}

 

////////////////////////////////////////////////////

以上就是我们的混合纹理Shader全部步骤。

我们在unity中直接看看效果吧。

 

上面用到了lerp(a,b,f)。如果我们想得到12之间的中间值,我们可以将lerp函数的第三个函数赋值为0.5,他将会返回1.5

这个函数很适合混合纹理,因为在一个RGBA纹理中单个通道的值就是单精度浮点值,通常值范围是0~1之间。

我们将提供的草地纹理 泥土纹理以及混合纹理的红色通道3个值作为lerp函数参数,这样我们得到物体表面每个像素值均为正确的混合颜色。

 

 code start-------------------------------------------------------------------------------

 

  

Shader "91YGame/TextureBlend" {
    Properties {
        //设置GUI;
        _MainTint("Diffuse Tint",Color)=(1,1,1,1)
        _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)=""
        _BlendTexture("Blend Texture",2D)=""
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        CGPROGRAM
        #pragma surface surf Lambert
        //变量;
        float4 _MainTint;
        float4 _ColorA;
        float4 _ColorB;
        sampler2D _RTexture;
        sampler2D _GTexture;
        sampler2D _BTexture;
        sampler2D _ATexture;
        sampler2D _BlendTexture;

        struct Input {
            float2 uv_RTexture;
            float2 uv_GTexture;
            float2 uv_BTexture;
            float2 uv_ATexture;
            float2 uv_BlendTexture;
        };

        void surf (Input IN, inout SurfaceOutput o) {
            //得到纹理讯息;
            float4 blendData = tex2D(_BlendTexture,IN.uv_BlendTexture);
            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);
            //进行纹理混合;
            float4 finalColor;
            finalColor = lerp(rTexData,gTexData,blendData.g);
            finalColor = lerp(finalColor,bTexData,blendData.b);
            finalColor = lerp(finalColor,aTexData,blendData.a);
            finalColor.a=1.0;
            //计算色调;
            float4 terrainLayers = lerp(_ColorA,_ColorB,blendData.r)*2;
            finalColor *= terrainLayers;
            finalColor = saturate(finalColor);
            //half4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = finalColor.rgb*_MainTint.rgb;
            o.Alpha = finalColor.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 



 

 code end--------------------------------------------------------------------------------