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

  • 相关阅读:
    软件系统的稳定性
    项目从.net 2.0 升级到。.net 4.0项目以后发现网站运行十分缓慢
    学习英语小助手(阅读粘贴的英文,使用MVVM)
    如何在IIS6,7中部署ASP.NET网站
    基于 IOCP 的通用异步 Windows Socket TCP 高性能服务端组件的设计与实现
    面向对象软件设计原则—— 软件实体的设计原则
    Django实战
    聊聊豆瓣阅读kindle版
    多线程的基本概念
    nopCommerce的源代码结构和架构
  • 原文地址:https://www.cnblogs.com/2Yous/p/4225111.html
Copyright © 2011-2022 走看看