[UnityShaderCookbook 读书笔记] [04] 多层纹理
来源:互联网 发布:开淘宝步骤 编辑:程序博客网 时间:2024/05/14 17:30
多层纹理
有时我们会需要给同一表面施加多层不同的纹理,这一情况在地形中常常出现,例如一个地形上同时会有泥土,岩石,草,花等不同纹理,此时,针对每一层纹理,我们都需要mask来表示该层纹理在地形上的分布。
如果给每一层纹理都附加一张mask图片,即使我们每张mask使用的都是灰度图,多张图片对系统依然是一个负担。在此,我们可以把每张灰度图作为一个通道,由此一张有4个通道(R,G,B,A)的图片就可以存储4张不同的mask。
每通道存储一个mask原理图解
下图为我们预期使用的4张不同的纹理
下图为我们的mask纹理,图示为各个通道的内容
我们需要先在属性段里添加5个2D贴图,分别为4张纹理以及1张mask纹理
Properties{ _RTexture ("Red Channel Texture", 2D) = ""{} _GTexture ("Green Channel Texture", 2D) = ""{} _BTexture ("Blue Channel Texture", 2D) = ""{} _ATexture ("Alpha Channel Texture", 2D) = ""{} _MaskTexture ("Mask Texture", 2D) = ""{}}
在SubShader块内的 CGPROGRAM 内再次声明这5个变量,
在 #pragma surface surf Lambert 后添加
sampler2D _RTexture;
sampler2D _GTexture;
sampler2D _BTexture;
sampler2D _ATexture;
sampler2D _MaskTexture;
再修改 surface 函数,在其中分别使用mask纹理的 R,G,B,A 通道来控制4张贴图。
将 surface 函数修改为
void surf (Input IN, inout SurfaceOutput o) { float4 rTexData = tex2D(_RTexture, IN.uv_MaskTexture); float4 gTexData = tex2D(_GTexture, IN.uv_MaskTexture); float4 bTexData = tex2D(_BTexture, IN.uv_MaskTexture); float4 aTexData = tex2D(_ATexture, IN.uv_MaskTexture); float4 maskData = tex2D(_MaskTexture, IN.uv_MaskTexture); float4 finalColor; finalColor = lerp(float4(1,1,1,1), rTexData, maskData.r); finalColor = lerp(finalColor, gTexData, maskData.g); finalColor = lerp(finalColor, bTexData, maskData.b); finalColor = lerp(finalColor, aTexData, maskData.a); finalColor.a = 1.0; finalColor = saturate(finalColor); o.Albedo = finalColor.rgb; o.Alpha = finalColor.a;}
最终实现的效果为
最终的多层纹理 Shader 为
Shader "HineNotes/CookbookCh_02/rgbaMask" { Properties { _RTexture ("Red Channel Texture", 2D) = ""{} _GTexture ("Green Channel Texture", 2D) = ""{} _BTexture ("Blue Channel Texture", 2D) = ""{} _ATexture ("Alpha Channel Texture", 2D) = ""{} _MaskTexture ("Mask Texture", 2D) = ""{} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert sampler2D _RTexture; sampler2D _GTexture; sampler2D _BTexture; sampler2D _ATexture; sampler2D _MaskTexture; struct Input { float2 uv_MaskTexture; }; void surf (Input IN, inout SurfaceOutput o) { float4 rTexData = tex2D(_RTexture, IN.uv_MaskTexture); float4 gTexData = tex2D(_GTexture, IN.uv_MaskTexture); float4 bTexData = tex2D(_BTexture, IN.uv_MaskTexture); float4 aTexData = tex2D(_ATexture, IN.uv_MaskTexture); float4 maskData = tex2D(_MaskTexture, IN.uv_MaskTexture); float4 finalColor; finalColor = lerp(float4(1,1,1,1), rTexData, maskData.r); finalColor = lerp(finalColor, gTexData, maskData.g); finalColor = lerp(finalColor, bTexData, maskData.b); finalColor = lerp(finalColor, aTexData, maskData.a); finalColor.a = 1.0; finalColor = saturate(finalColor); o.Albedo = finalColor.rgb; o.Alpha = finalColor.a; } ENDCG } FallBack "Diffuse"}
在上面的 surf 函数中,我们用到了CGFX 标准库 中的内建函数 lerp()
lerp函数的作用,即是在 a 与 b 之间利用 f 进行线性插值。举例来说,当 f = 0 时,插值结果为 a, f = 1 时, 插值结果为 b。
下图为 lerp() 函数的作用图解
在 shader 代码当中,我们首先将 R 贴图与白色利用 R mask 线性插值,再将其结果利用 B mask 与 B 贴图线性插值,如此反复对每个贴图与原先的结果进行线性插值,最终就得到了混合后的结果。
- [UnityShaderCookbook 读书笔记] [04] 多层纹理
- [UnityShaderCookbook 读书笔记] [02] 光照模型
- [UnityShaderCookbook 读书笔记] [03] UV 动画
- [UnityShaderCookbook 读书笔记] [01] Unity Shader 基础
- 多层纹理混合
- 图形学 - 多层纹理技术的底层原理
- 3D地形多层纹理混合加阴影渲染方法
- 3D地形多层纹理混合加阴影渲染方法
- 3D地形多层纹理混合加阴影渲染方法
- 修改ETM,使之支持多格多层纹理
- 3D地形多层纹理混合加阴影渲染方法
- 3D地形多层纹理混合加阴影渲染方法
- 3D地形多层纹理混合加阴影渲染方法
- 3D地形多层纹理混合加阴影渲染方法
- 3D地形多层纹理混合加阴影渲染方法
- 基于纹理与颜色的多层背景差分
- 读书笔记——各向异性纹理过滤
- 纹理
- Xcode使用xcconfig文件配置环境
- 1、什么是设计模式
- Redis在Linux的安装教程
- PL/SQL Boolean类型
- 通过观影兴趣预测用户画像之年龄属性
- [UnityShaderCookbook 读书笔记] [04] 多层纹理
- 第七章
- 2、说说多态
- 第八章
- 新诗
- 算法复杂度函数级T(n)非O(n)分析
- java 调用shell命令
- 3、面向对象接口
- FISTA的由来:从梯度下降法到ISTA & FISTA