Unity Shader入门精要第七章 基础纹理之遮罩纹理

2023-11-20

Unity系列文章目录

前言

遮罩纹理(mask texture)是本章要介绍的最后一种纹理,它非常有用,在很多商业游戏中
都可以见到它的身影。那么什么是遮罩呢?简单来讲,遮罩允许我们可以保护某些区域,使它们
免于某些修改。例如,在之前的实现中,我们都是把高光反射应用到模型表面的所有地方,即所
有的像素都使用同样大小的高光强度和高光指数。但有时,我们希望模型表面某些区域的反光强
烈一些,而某些区域弱一些。为了得到更加细腻的效果,我们就可以使用一张遮罩纹理来控制光
照。另一种常见的应用是在制作地形材质时需要混合多张图片,例如表现草地的纹理、表现石子
的纹理、表现裸露土地的纹理等,使用遮罩纹理可以控制如何混合这些纹理。
使用遮罩纹理的流程一般是:通过采样得到遮罩纹理的纹素值,然后使用其中某个(或某几
个)通道的值(例如texel.r)来与某种表面属性进行相乘,这样,当该通道的值为0 时,可以保
护表面不受该属性的影响。总而言之,使用遮罩纹理可以让美术人员更加精准(像素级别)地控
制模型表面的各种性质。

一、实践

在本节中,我们将学习如何使用一张高光遮罩纹理,逐像素地控制模型表面的高光反射强度。
图17.20 显示了只包含漫反射、未使用遮罩的高光反射和使用遮罩的高光反射的对比效果。
▲图7.20 使用高光遮罩纹理。从左到右:只包含漫反射,未使用遮罩的高光反射,使用遮罩的高光反射
我们使用的遮罩纹理如图7.21 所示。可以看出,遮罩纹理可以让我们更加精细地控制光照细
节,得到更细腻的效果。
为了在Unity Shader 中实现上述效果,我们需要进行如下准备工作。
(1)在Unity 中新建一个场景。在本书资源中,该场景
名为Scene_7_4。在Unity 5.2 中,默认情况下场景将包含一
个摄像机和一个平行光,并且使用了内置的天空盒子。在
Window -> Lighting -> Skybox 中去掉场景中的天空盒子。
(2)新建一个材质。在本书资源中,该材质名为
MaskTextureMat。
(3)新建一个Unity Shader。在本书资源中,该Unity
Shader 名为Chapter7-MaskTexture。把新的Unity Shader
赋给第2 步中创建的材质。
(4)在场景中创建一个胶囊体,并把第2 步中的材质
赋给该胶囊体。
(5)保存场景。
打开新建的Chapter7-MaskTexture,删除所有已有代码,并进行如下修改:
( 1)首先,我们需要为这个 Shader 起一个名字:
Sh ader “Unity Shaders Book/Chapter 7/Mask Texture” {
( 2)我们需要在 Properties 语义块中声明更多的变量来控制高光反射:
Properties {
_Color (“Color Tint”, Color) = (1,1,1,1)
_MainTex (“Main Tex”, 2D) = “white” {}
_BumpMap (“Normal Map”, 2D) = “bump” {}
_BumpScale(“Bump Scale”, Float) = 1.0
_SpecularMask (“Specular Mask”, 2D) = “white” {}
_SpecularScale (“Specular Scale”, Float) = 1.0
_Specular (“Specular”, Color) = (1, 1, 1, 1)
_Gloss (“Gloss”, Range(8.0, 256)) = 20
}
上面属性中的_SpecularMask 即是我们需要使用的高光反射遮罩纹理,_SpecularScale 则是用
于控制遮罩影响度的系数。

在这里插入图片描述

在这里插入图片描述
(3)然后,我们在SubShader 语义块中定义了一个Pass 语义块,并在Pass 的第一行指明了该
Pass 的光照模式:
SubShader {
Pass {
Tags { “LightMode”=“ForwardBase” }
LightMode 标签是Pass 标签中的一种,它用于定义该Pass 在Unity 的光照流水线中的角色。
(4)然后,我们使用CGPROGRAM 和ENDCG 来包围住Cg 代码片,以定义最重要的顶点着
色器和片元着色器代码。我们使用#pragma 指令来告诉Unity,我们定义的顶点着色器和片元着色
器叫什么名字。在本例中,它们的名字分别是vert 和frag:
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
(5)为了使用Unity 内置的一些变量,如_LightColor0,还需要包含进Unity 的内置文件
Lighting.cginc:
#include “Lighting.cginc”
(6)随后,我们需要定义和Properties 中各个属性类型相匹配的变量:
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _BumpMap;
float _BumpScale;
sampler2D _SpecularMask;
float _SpecularScale;
fixed4 _Specular;
float _Gloss;
我们为主纹理_MainTex、法线纹理_BumpMap 和遮罩纹理_SpecularMask 定义了它们共同使
用的纹理属性变量_MainTex_ST。这意味着,在材质面板中修改主纹理的平铺系数和偏移系数会
同时影响3 个纹理的采样。使用这种方式可以让我们节省需要存储的纹理坐标数目,如果我们为
每一个纹理都使用一个单独的属性变量TextureName_ST,那么随着使用的纹理数目的增加,我们
会迅速占满顶点着色器中可以使用的插值寄存器。而很多时候,我们不需要对纹理进行平铺和位
移操作,或者很多纹理可以使用同一种平铺和位移操作,此时我们就可以对这些纹理使用同一个
变换后的纹理坐标进行采样。
( 7)定义顶点着色器的输入和输出结构体:
struct a2v {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 lightDir: TEXCOORD1;
float3 viewDir : TEXCOORD2;
};
(8)在顶点着色器中,我们对光照方向和视角方向进行了坐标空间的变换,把它们从模型空
间变换到了切线空间中,以便在片元着色器中和法线进行光照运算:
v2f vert(a2v v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
TANGENT_SPACE_ROTATION;
o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz;
o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex)).xyz;
return o;
}
(9)使用遮罩纹理的地方是片元着色器。我们使用它来控制模型表面的高光反射强度:
fixed4 frag(v2f i) : SV_Target {
fixed3 tangentLightDir = normalize(i.lightDir);
fixed3 tangentViewDir = normalize(i.viewDir);
fixed3 tangentNormal = UnpackNormal(tex2D(_BumpMap, i.uv));
tangentNormal.xy *= _BumpScale;
tangentNormal.z = sqrt(1.0 - saturate(dot(tangentNormal.xy, tangentNormal.xy)));
fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(tangentNormal, tangentLightDir));
fixed3 halfDir = normalize(tangentLightDir + tangentViewDir);
// Get the mask value
fixed specularMask = tex2D(_SpecularMask, i.uv).r * _SpecularScale;
// Compute specular term with the specular mask
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(tangentNormal,
halfDir)), _Gloss) * specularMask;
return fixed4(ambient + diffuse + specular, 1.0);
}
环境光照和漫反射光照和之前使用过的代码完全一样。在计算高光反射时,我们首先对遮罩
纹理_SpecularMask 进行采样。由于本书使用的遮罩纹理中每个纹素的rgb 分量其实都是一样的,
表明了该点对应的高光反射强度,在这里我们选择使用r 分量来计算掩码值。然后,我们用得到
的掩码值和_SpecularScale 相乘,一起来控制高光反射的强度。
需要说明的是,我们使用的这张遮罩纹理其实有很多空间被浪费了—它的rgb 分量存储的
都是同一个值。在实际的游戏制作中,我们往往会充分利用遮罩纹理中的每一个颜色通道来存储
不同的表面属性,我们会在7.4.2 节中介绍这样一个例子。
(10)最后,我们为该Unity Shader 设置了合适的Fallback:
Fallback “Specular”
7.4.2 其他遮罩纹理
在真实的游戏制作过程中,遮罩纹理已经不止限于保护某些区域使它们免于某些修改,而是
可以存储任何我们希望逐像素控制的表面属性。通常,我们会充分利用一张纹理的RGBA 四个通
道,用于存储不同的属性。例如,我们可以把高光反射的强度存储在R 通道,把边缘光照的强度
存储在G 通道,把高光反射的指数部分存储在B 通道,最后把自发光强度存储在A 通道。
在游戏《DOTA 2》的开发中,开发人员为每个模型使用了4 张纹理:一张用于定义模型颜色,
一张用于定义表面法线,另外两张则都是遮罩纹理。这样,两张遮罩纹理提供了共8 种额外的表
面属性,这使得游戏中的人物材质自由度很强,可以支持很多高级的模型属性。读者可以在他们
的官网上找到关于《DOTA 2》的更加详细的制作资料,包括游戏中的人物模型、纹理以及制作手
册等。这是非常好的学习资料。
在这里插入图片描述

参考

Unity Shader入门精要
冯乐乐

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity Shader入门精要第七章 基础纹理之遮罩纹理 的相关文章

  • unity网络资源导入

    1 找到需要导入的文件 这里导入fbx格式 2 打开unity界面 在Asset目录下创建文件夹FBX 将需要导入的fbx预制体或整个文件夹拖入创建的FBX文件夹下 3 选中需要的fbx预制体并拖至场景中 4 双击定位到当前物体 5 找到需
  • c#获取cpu序列号

  • Unity 分块延迟渲染01 (TBDR)

    现代移动端图形体系结构的概述 现代SoC通常会同时集成CPU和GPU CPU被用于处理需要低内存延迟的序列 大量分支的数据集 其晶体管用于流控制和数据缓存 GPU为处理大型 未分支的数据集 如3D渲染 晶体管专用于寄存器和算术逻辑单元 而不
  • Unity中级客户端开发工程师的进阶之路

    上期UWA技能成长系统之 Unity高级客户端开发工程师的进阶之路 得到了很多Unity开发者的肯定 通过系统的学习 可以掌握游戏性能瓶颈定位的方法和常见的CPU GPU 内存相关的性能优化方法 UWA技能成长系统是UWA根据学员的职业发展
  • Unity-AR 简介

    Unity AR 简介 现有Unity AR Sdk ARKit 苹果推出的AR开发平台 ARCore Google 推出的增强现实 SDK ARFoundation ARFoundation是ARKit XR插件和ARCore XR插件
  • FBX导入Unity中模型没有材质的处理

    一 3dMax导出FBX时的注意事项 导出时 确保maps文件存在 里面放着fbx用到的image 二 在Unity中的设置 1 文件拖入Unity的Assets文件夹中 2 查看模型的材质是否存在 如下所示 材质为None 此时拖入sce
  • Unity动画系统详解

    目录 动画编辑器 编辑器面板 动画复用 前言 人形重定向动画 Humanoid 通用动画 Generic 旧版本动画 Legacy 动画控制器 系统状态 切换条件 状态机脚本 IK动画 反向动力学 BlendTree 混合树 Animato
  • Unity3d 插件 系列——DoTweenPro介绍(图文详细+案例)

    Unity3d 插件 系列 DoTweenPro介绍 图文详细 案例 前言 一 DoTweenPro简介 二 DoTweenPro安装 三 DoTweenPro主要组件 1 DoTweenAnimation 2 DoTweenPath 3
  • Unity中UI框架的使用1-添加面板、显示Loading页面

    其中BasePanel和Canvas都是挂在面板的预制物上的 1 导入我们的UI框架 本篇文章中有用的是两个UIPanelType NUIManager和NBasePanel 会放在文章最后供大家使用 2 先将我们做好的Panel设置成预制
  • unity中创建询问弹出窗口

    在开发过程中进程会遇到需要弹出一个窗口询问用户是否进行的操作 今天就来制作一个这样弹出窗口 然后根据弹出窗口的选择内容不同进行不同的操作 本例中主要是为了删除一个数据 而在删除数据操作前需要得到用户的一个确认操作 这里面主要用到了Notif
  • unity工程崩溃资源找回

    1 Unity死机未保存场景 当你在Unity中编辑场景 突然死机时 可以在项目文件目录中找到Temp文件夹 双击文件夹 找到 Backupscenes文件夹 把后缀为 backup的文件后缀改为 unity 然后拖进Unity的Proje
  • unity dots jobSystem 记录

    Looking for a way to get started writing safe multithreaded code Learn the principles behind our Job System and how it w
  • unity3d image组件不显示

    需要将UI组件放到画布下面
  • 【原神游戏开发日志1】缘起

    原神游戏开发日志1 缘起 版权声明 本文为 优梦创客 原创文章 您可以自由转载 但必须加入完整的版权声明 文章内容不得删减 修改 演绎 相关学习资源见文末 大家好 最近看到原神在TGA上频频获奖 作为一个14年经验的游戏开发行业的老兵 我就
  • 【Unity】运行时创建曲线(贝塞尔的运用)

    Unity 运行时创建线 贝塞尔的运用 1 实现的目标 在运行状态下创建一条可以使用贝塞尔方法实时编辑的网格曲线 2 原理介绍 2 1 曲线的创建 unity建立网格曲线可以参考 Unity程序化网格体 的实现方法 主要分为顶点 三角面 U
  • 【Unity】运行时创建曲线(贝塞尔的运用)

    Unity 运行时创建线 贝塞尔的运用 1 实现的目标 在运行状态下创建一条可以使用贝塞尔方法实时编辑的网格曲线 2 原理介绍 2 1 曲线的创建 unity建立网格曲线可以参考 Unity程序化网格体 的实现方法 主要分为顶点 三角面 U
  • U3D游戏开发中摇杆的制作(UGUI版)

    在PC端模拟摇杆 实现玩家通过控制摇杆让玩家移动 以下是完整代码 using System Collections using System Collections Generic using UnityEngine using Unity
  • U3D游戏开发中摇杆的制作(NGUI版)

    在PC端模拟摇杆 实现控制摇杆让玩家或者物体移动 以下是完整代码 using System Collections using System Collections Generic using UnityEngine public clas
  • 游戏开发常见操作梳理之NPC任务系统

    多数游戏存在任务系统 接下来介绍通过NPC触发任务的游戏制作代码 using System Collections using System Collections Generic using UnityEngine
  • 游戏开发中常见系统梳理之背包系统的实现一

    游戏中几乎都存在大大小小的背包系统 接下来我将讲述背包系统具体是如何实现的 完整源码 以下是使用unity NGUI实现 使用txt配置的方法 后续更新UGUI Json实现的背包系统敬请期待 背包中的物品我们常常将其制作成预设体 通过改变

随机推荐

  • Java基础之随机生成数字和字母

    原文地址 http blog csdn net yaodong y article details 8115250 字母与数字的ASCII码 目 前计算机中用得最广泛的 字符集及其编码 是由美国国家标准局 ANSI 制定的ASCII码 Am
  • OpenGL视图变换及gluLookAt

    视图变换 即相机变换 其作用是把相机放在指定位置并使其对准场景 该变换是针对相机的变换 不会影响到模型 视图变换决定了相机的位置与方向 因此可以通过视图变换来改变相机位置与方向 从而达到从各个不同的位置与角度来观察同一个物体的情形 进行视图
  • SHAP显示原始特征

    1 问题描述 SHAP用于特征解释 对于机器学习方法往往需要对原始特征进行编码 而SHAP在绘制单个样本时 会显示每个特征及其取值 而这个取值已经是编码后的 通常无法确定其含义 如 下图所示的拍卖公司 城市和作者信息 预期达到的效果 2 实
  • 【西瓜书】4-决策树

    文章目录 4 1 基本流程 4 2 划分 4 2 1 信息增益 ID3 4 2 2 信息增益率 C 45 4 2 3 基尼指数 CART 4 3 剪枝处理 4 4 连续与缺失值 4 4 2 连续值处理 4 4 1 缺失值处理 4 5 多变量
  • Anchor是什么?

    1 选择性搜索 Selective Search 先介绍一下传统的人脸识别算法 是怎么检测出图片中的人脸的 以下图为例 如果我们要检测图中小女孩的人脸位置 一个比较简单暴力的方法就是滑窗 我们使用不同大小 不同长宽比的候选框在整幅图像上进行
  • crmeb重新安装_手动安装教程 · CRMEB 知识付费版 帮助文档 · 看云

    手动安装 1 创建数据库 倒入数据库文件 数据库文件目录 public install zhishifufei sql 2 修改数据库连接文件 配置文件路径 application database php 数据库类型 type gt my
  • vagrant启动openshift

    1 Install Vagrant 2 Install VirtualBox Ex yum install VirtualBox from the RPM Fusion repository 3 In your bashrc file or
  • 元胞自动机算法汇总含matlab代码_数学建模(十三)

    元胞自动机理论 许多复杂的问题都可以通过元胞自动机来建立模型 元胞自动机实质上是定义在一个具有离散 有限状态的元胞组成的元胞空间上 并按照一定的局部规则 在离散的时间维度上演化的动力学系统 元胞又可称为单元 细胞 是元胞自动机的最基本的组成
  • 【hortonworks/registry】registry 如何添加新的类型 支持 json

    1 概述 hortonworks registry 支持json 但是要自己扩展 有相关接口 支持基本类型 支持自定义对象类型 支持集合类型 map array null 支持嵌套结构 registry支持的数据类型有好几种 其中有Avro
  • STM32F103C8T6+PWM+DMA驱动 WS2812灯带

    STM32 PWM DMA驱动 WS2812灯带 文章目录 1 理论 2代码 理论 1 WS2812参考数据手册 https wenku baidu com view 0925958fba68a98271fe910ef12d2af90342
  • 基于Matlab卡尔曼滤波的IMU和GPS组合导航数据融合(附上源码+数据)

    本文介绍了如何使用Matlab实现惯性测量单元 IMU 和全球定位系统 GPS 组合导航数据融合的卡尔曼滤波算法 通过将IMU和GPS的测量数据进行融合 可以提高导航系统的精度和鲁棒性 我们将详细介绍卡尔曼滤波的原理和实现步骤 并给出源码
  • SpringBoot使用Pio-tl动态填写合同(文档)

    poi tl poi template language 是Word模板引擎 使用Word模板和数据创建很棒的Word文档 poi tl官方网址 项目中有需求需要动态填充交易合同 因此想到了使用poi tl技术来实现 一 引入依赖
  • Keil5无法进入debug(卡死在启动文件)

    Keil5无法进入debug 卡死在启动文件 出现的情况 运行一直卡死在启动文件 例如startup stm32f103xe s 而主程序的箭头也只有一个 两个箭头的运行行在启动文件 debug一直无法运行 解决办法 你在程序中使用了pri
  • Qml与C++交互4:C++信号与Qml的槽函数的连接

    Qml与C 交互4 C 信号与Qml的槽函数的连接 使用场景 整体思路 1 建立C 信号 2 C 实例注册到qml 3 qml中建立槽函数 Connections 类型 建立槽函数 运行结果 使用属性 更多资讯 知识 微信公众号搜索 上官宏
  • OpenCV项目编译错误

    编译遇到如下错误 opencv 3 4 4 modules highgui src window gtk cpp 1062 error 218 No OpenGL support Library was built without Open
  • 长春地铁一号线作业

    长春一号线作业 代码如下 public class 第一次作业 public static void main String args System out println 北环城站 一匡街 胜利公园 解放大路 工农广场 卫星广场 华庆路
  • 卡尔曼及扩展卡尔曼滤波详细推导-来自DR_CAN视频

    卡尔曼及扩展卡尔曼滤波详细推导 来自DR CAN视频 见知乎https zhuanlan zhihu com p 585819291
  • Pytorch权重初始化方法——Kaiming、Xavier

    Pytorch权重初始化方法 Kaiming Xavier 结论 结论写在前 Pytorch线性层采取的默认初始化方式是Kaiming初始化 这是由我国计算机视觉领域专家何恺明提出的 我的探究主要包括 为什么采取Kaiming初始化 考察K
  • window10 设置 cmd 与 PowerShell 格式UTF-8

    win R键 输入 regedit 进入 如果进入不了就去下载 regedit cmd 接下来我们进入对应目录添加对应字符串 好了我们重启vscode运行即可 PowerShell 原CodePage数值数据 更改CodePage数值数据
  • Unity Shader入门精要第七章 基础纹理之遮罩纹理

    Unity系列文章目录 文章目录 Unity系列文章目录 前言 一 实践 参考 前言 遮罩纹理 mask texture 是本章要介绍的最后一种纹理 它非常有用 在很多商业游戏中 都可以见到它的身影 那么什么是遮罩呢 简单来讲 遮罩允许我们