UnityShader之压缩和混合纹理贴图

纹理压缩,大多情况会在地形着色器中使用,当我们遇到需要将一组纹理混合显示在一个游戏物体上的需求时,我们就需要使用一种特殊的纹理操作或者纹理压缩的方式来完美的进行纹理混合。

准备工作:四张地形贴图 和 包含四个混合纹理的灰度贴图

Shader "Example / 001" 
{
    Properties 
    {
        _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)
        //2D贴图
        _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
        #pragma target 4.0

        //创建与CG内的属性的连接
        float4 _MainTint;
        float4 _ColorA;
        float4 _ColorB;
        sampler2D _RTexture;
        sampler2D _GTexture;
        sampler2D _BTexture;
        sampler2D _BlendTex;
        sampler2D _ATexture;

        struct Input 
        {
            //获取每个纹理的uv坐标,方便对其偏移
            float2 uv_RTexture;
            float2 uv_GTexture;
            float2 uv_BTexture;
            float2 uv_ATexture;
            float2 uv_BlendTex;
        };

        void surf (Input IN, inout SurfaceOutput o) 
        {
            //从混合纹理采样,获取像素数据
            //返回float4(rgba or xyzw)
            float4 blendData = tex2D(_BlendTex, IN.uv_BlendTex);

            //从这些纹理中获取我们需要的纹理uv数据
            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);

            //需要一个新的RGBA值来混合所有的纹理
            //lerp插值的计算前几节说过了,举个例子 ,blendData.g = 0的时候函数返回rTexData,blendData.g = 1的时候,函数返回gTexData
            //所以当gTexData的值更偏向哪一边的时候,显示出来的颜色就更偏向哪一边。
            float4 finalColor;
            finalColor = lerp(rTexData, gTexData, blendData.g);
            finalColor = lerp(finalColor, bTexData, blendData.b);
            finalColor = lerp(finalColor, aTexData, blendData.a);
            finalColor.a = 1.0;

            //添加我们的地形着色
            //混合纹理的r值将在_ColorA _ColorB中进行插值计算得出
            float4 terrainLayers = lerp(_ColorA, _ColorB, blendData.r);
            finalColor *= terrainLayers;
            //最终颜色取(0,1)
            finalColor = saturate(finalColor);

            o.Albedo = finalColor.rgb * _MainTint.rgb;
            o.Alpha = finalColor.a;
        }
        ENDCG
    } 
    FallBack "Diffuse"
}

需要注意的是
lerp插值计算, 这个函数使我们得到参数1 和 参数2之间的值 并使用参数3来计算混合量

你可能感兴趣的:(unity3d特效)