zoukankan      html  css  js  c++  java
  • Unity3D ShaderLab压缩混合纹理贴图

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

  • 相关阅读:
    Kubernetes 认证(证书)过期怎么办
    JavaScript 全屏显示窗口
    IE6下很无语的问题,不知为何
    项目开发-让设计模式成为一种心智(转)
    CSS中Float概念相关文章采撷
    随记浏览器兼容性
    常用正则表达式
    ASP.NET 调用Delphi DLL问题
    ASP.NET调用DELPHI DLL
    转:Oracle 排序中常用的NULL值处理方法
  • 原文地址:https://www.cnblogs.com/2Yous/p/4225111.html
Copyright © 2011-2022 走看看