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

}

2,SubShader申明变量

#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)。如果我们想得到1和2之间的中间值,我们可以将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--------------------------------------------------------------------------------

时间: 2024-10-25 10:40:34

Unity3D ShaderLab压缩混合纹理贴图的相关文章

Unity3D ShaderLab 使用渐变纹理着色

Unity3D ShaderLab 使用渐变纹理着色 在我们编写着色器的过程中,还可以通过渐变纹理来控制漫反射的光照颜色.这种做法同样在VALVE的军团要塞2中及其流行. 前期,请准备一个渐变色的图片.再把我们之前的Hlf Lambert的代码稍加修改. 1:Properties添加GUI上的图片纹理属性>_RampTex ("Ramp Texture", 2D) = "" 2:在SubShader中申明图片纹理>sampler2D _RampTex;

Unity Shaders and Effects Cookbook (2-4) 压缩和混合纹理贴图:使用灰度图存储插值信息

这一节看了几次才慢慢的读懂. 首先是这个灰度图,为什么叫灰度图,是因为 这个图片中的 R.G.B 存放的都是同一份数据,打开Unity 来调一下颜色看看 更直观. 可以看到,当 R.G.B 三个值相同的时候,图片是只有黑白,而丢失了其它的颜色的,所以我们叫灰度图. 什么时候用到灰度图? 本文转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn 比如说高度图,在这个坐标的点,海拔高,就记作 1,海拔低就记作0 .把这一份数据 同时存储到

Unity3D ShaderLab 简单的立方体图反射

Unity3D ShaderLab 简单的立方体图反射 反射是着色器模拟现实环境的一个关键因素,它能使我们的着色器渲染效果更加具备视觉冲击,因为他利用了我们周围的环境, 让着色器反射外界的场景信息并将他们反射到材质表面来模拟外部环境,所以我们会使用立方图[CubeMap]的6张纹理来模拟环境的色彩情况. 首先,创建Shader,创建材质球,准备立方图,双击Shader,进入代码编辑器. 从Properties 到CGPROGRAM,再到surf,本次功能较为简单,先看代码. code start

Unity3D ShaderLab 立方体图的反射遮罩

Unity3D ShaderLab 立方体图的反射遮罩 上一篇,简单的介绍了立方体图的反射,那么我们能不能使用一张问题对其进行指定遮罩呢?这样美工可以更好的控制图像的效果. 我们接着使用上一篇的shader代码,新建一个材质球,本次修改也是数行代码而已,所以 直接看完成代码. code start -------------------------------------------------------------------- Shader "91YGame/CubeMask" 

Unity3D ShaderLab 使用贴图对模型的高光进行遮罩

Unity3D ShaderLab 使用贴图对模型的高光进行遮罩 前面研究了高光效果的实现,再说说现很多游戏用到的高光贴图技术,因为它可以让3D美工更容易控制最终的视觉效果. 这也就为我们提供了另外的方式,我们可以在同一个着色器上实现垫型表面和光亮表面,也可以使用贴图来控制镜面高光的范围或者高光强度, 以实现一个表面是广泛的镜面高光而另一面确是细小的高光. 新建一个shader,一个材质球.老规矩双击shader脚本,在编辑器中编写代码吧. 1.Properties: Properties {

unity3d 纹理贴图移动特效产生岩浆、瀑布效果

纹理贴图移动特效产生岩浆.瀑布效果 原理是改变动态改变纹理坐标uv的值,使之移动 首先准备好一张贴图 建立一个shader 变量一览: _MainTex 主纹理贴图 _MainTint 主要颜色 _ScrollXSpeed x轴移动速度 _ScrollYSpeed  y轴移动速度 Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _MainTint ("Diffuse Tint", Col

Unity3D ShaderLab 立方体图的菲涅尔反射

Unity3D ShaderLab 立方体图的菲涅尔反射 菲涅尔反射是反射类型中比较常见的一种类型,当我们的视线正对物体表面,那么反射量会明显增加, 我们几乎可以在任何支持反射类型的物体表面看到这种情况,我们接下来就来实现这种反射效果过. 还是先创建Shader和 Material,沿用上一节的立方体图.代码变动较少,直接看下面的完成代码: code start -------------------------------------------------------------------

Unity3D ShaderLab立方体图的法线渲染

Unity3D ShaderLab立方体图的法线渲染 某些情况下,我们希望立方体图的材质球上产生法线效果,来更多的表现细节,比如菱形花纹的玻璃,冰块的表面. 在帧数的协调下,我们可以通过input结构体的另一个内置参数来传递我们的法线贴图.下面 我们就一步步实现. 首先,新建Shader,在新建材质球,准备立方体图,法线贴图.双击shader进入脚本编辑. 本次的代码修改依然是和之前的立方体图的反射遮罩差不多,所以就直接看完成的代码吧. code start ------------------

Unity3D ShaderLab法线贴图

Unity3D ShaderLab法线贴图 说到法线贴图,应该算是我们最常使用的一种增强视觉效果的贴图.将法线贴图的各个像素点座位模型的法线,这样我们的光照可以模拟出高分辨率的效果, 同时也保持较低的多边形数.法线贴图通常存储在一个普通的rgb图片,他的rgb分量分别对应了曲面法线的xyz坐标. 在Unity中,会通过UnpackNormals()函数来使用法线贴图,这使得在表面着色范围内为我们的着色器添加使用法线的过程变得更容易. 首先,创建一个shader和材质球.我们开始修改shader代