首页 > 其他分享 >[官方培训] 07-UE材质基础 | 孙丹璐 Epic

[官方培训] 07-UE材质基础 | 孙丹璐 Epic

时间:2024-03-29 22:46:58浏览次数:16  
标签:法线 07 物体 深度 UE 材质 Epic 节点 半透明

传送门:[官方培训]07-UE材质基础 | 孙丹璐 Epic_哔哩哔哩_bilibili


一. 材质

1.1 什么是材质

  • 在自然界中,光线照射到平面后,按法线方向发生反射,被人眼所见
  • 如果平面透光率较高,则光线部分进入平面内部,经过多重折射后削弱,被人眼所见

 

  1. 材质
    • 决定了光源是如何与物体表面交互,定义了场景中对象的表面属性
    • 反射(漫反射、镜面反射)
    • 折射
    • 透射

 

    • 本质上应用于 Mesh 并控制 Mesh 的视觉外观
    • 固体(塑料,岩石,木板,铁块…)
    • 次表面(皮肤,树叶,玉石…)
    • 透明(玻璃,水)

 

    • 为了更逼真的模拟光源与物体表面的交互过程,UE 使用了 PBR 模型(Physically Based Rendering 基于物理的渲染,由现实世界的物理规律提取出来的基本理论所构成的渲染技术集合)
    • PBR 材质的 4 个基础属性:漫反射,粗糙度,金属度,高光度
    • 一个材质可能需要更多:法线,环境光遮蔽(AO),置换纹理(WPO)…

 

  1. 材质编辑器
    • 材质编辑器

 

    • UE 材质使用 HLSL 的专门编码语言创建,通过 Window 窗口 - Shader 代码,查看当前材质节点被转换的 HLSL 代码(材质的底层很复杂,引擎预设了多套模板,具体使用哪套模板,由材质细节面板决定,编辑器中连接的节点相当于模板中的变量)

 

  1. PBR 材质
    • Physical Based Rendering(PBR):基于物理的渲染

 

    • 基于物理的材质最重要的输入包括:
    • Metallic 金属度:决定材质是否为金属

 

    • Specular 高光度:仅对非金属(Metallic != 1)有效

 

    • Roughness 粗糙度:决定物体表面光滑与否,需要高精度存储

 

    • PBR 材质常用概念:
    • UE 的 PBR 材质系统中引入了各种 BRDF 理论模型,BRDF 双向反射分布函数(Bidirectional Reflectance Distribution Function)是建立在光学物理与计算机图形学的基础上,用于描述光线反射现象的数学模型

 

    • F0(Fresnel Reflectance at 0 Degrees)在0度的菲尼尔反射率:当光线笔直或垂直(以0度角)撞击表面时,该光线的一部分会被反射为镜面反射,使用表面的折射率(IOR),可以推导出反射量,即法线方向的反射率属性

 

 

1.2 材质基础

1.2.1 Base Color 基础颜色

  1. Base Color 基础颜色定义的是材质的整体颜色,包含 RGB 通道(范围 0-1)
  2. 对于非金属材质,Base Color 基础颜色代表漫反射信息
  3. 输入 Base Color 基础颜色需避免:
    1. 纯黑 / 纯白(自然界无此物质)
    2. 纹理不带光影信息
  1. 使用纹理时,注意材质内纹理采样器应当和纹理本身一致(如:是线性还是sRGB)

 

 

1.2.2 Roughness 粗糙度

  1. Roughness 粗糙度决定物体表面光滑与否(范围 0-1,默认 0.5),通常用比较高的精度存储它
  2. 如果粗糙度存储在纹理中,一般选用 G 通道存储粗糙度(默认 DXT1 压缩方法下,RGB 通道中的 G 通道,精度最高,存放信息最多)
  3. 一般在 Specular 高光度为 0.5 的情况下,微调 Roughness 粗糙度

 

 

1.2.3 Metallic 金属度

  1. Metallic 金属度决定该材质是否为金属(默认为 0,非金属),对应决定了 F0 属性的输入方式(Specular 高光度 / Base Color 基础颜色)
  2. 当 Metallic != 1(非金属)时,则该材质只有高光反射,其 F0 属性通过 Base Color 基础颜色输入

 

  1. 以下图纯白材质为例,原则上 Metallic 金属度是一个非 0 即 1 的布尔值,但允许其存在中间值,用来描述部分特殊材质(如:细沙、有刮痕的金属表面等)的精度

 

 

1.2.4 Specular 高光度

  1. 仅对非金属有效(Metallic != 1,范围 0-1,默认 0.5)
  2. 对于非金属(Metallic != 1),F0 的值由 Specular 高光度决定(Specular 高光度范围 0-1,对于 F0 范围 0-0.08,Specular 高光度默认 0.5,则对应 F0 为 0.04)
  3. 由于对应的 F0 范围较小,且 Specular 高光度的默认值可以匹配绝大部分非金属 F0,通常不需要调整 Specular 高光度的值
  4. 特殊用法:屏蔽凹陷等微阴影处的高光(调低 Specular 高光度,甚至设置为 0)

 

  1. 材质制作技巧:
    1. 首先定义材质是否为金属,并输入 Base Color 基础颜色
    2. 在 Specular 高光度为 0.5 的情况下,微调 Roughness 粗糙度
    3. 对 Roughness 粗糙度效果满意后,二次调整特殊部分(如:刮痕凹陷处)的 Metallic 金属度和 Roughness 粗糙度

 

 

1.2.5 Normal 法线

  1. 法线:通过改变像素与光的交互方向,为模型表面增加细节(模型本身多边形并没有发生改变)
  2. 模型的法线:
    1. 模型由多个三角面片构成,如:下图中的模型,底面由 2 个三角面片构成

 

    1. 对于每个面,法线方向以顶点法线的方式存在于构成它的 3 个顶点方向中,如:下图中的模型,每个顶点存储了 3 个方向的法线,需要确保顶点相邻的 3 个三角面片的面法线方向正确

 

    1. 如果希望改变三角面片上或三角面片上每个顶点的法线,可以使用法线纹理(法线纹理:由高模与低模的高度差生成),连接材质的 Normal 法线节点,有了丰富的光影细节

 

    1. 但注意,Normal 法线纹理仅模拟视觉凹凸感,不会真实改变模型(如果以一个平视角观察模型,就穿帮了)

 

  1. 对 Normal 法线进一步处理
    1. 按距离,混合多层法线改善近距离的表现
    2. 融合 2 张法线纹理:法线是在切线空间归一化的值,如果直接相加 2 张法线,则范围大于 1 ,会丢失法线细节,需要使用 BlendAngleCorrectedNormals 节点,正确融合 2 张法线纹理

 

 

1.2.6 Tangent 切线

  1. 与法线纹理类似,可以将切线纹理输入到 Tangent 切线,以调整模型的切线方向
  2. 在静态网格体编辑器中,查看模型切线

 

 

1.2.7 Anisotropy 各向异性

  1. Anisotropy 各向异性:可以调整高光的形态,决定了高光沿切线拉伸的范围(范围 0-1,0 为没有各向异性效果,高光不拉伸)

 

 

1.2.8 Emissive Color 自发光颜色

  1. Emissive Color 自发光颜色:材质的视觉发光效果,一般是高于 1 的值

 

  1. 数值过大,则颜色偏白(过曝)

 

 

1.2.9 World Position Offset 全局位置偏移

  1. World Position Offset 全局位置偏移:针对顶点的形变
    1. (0,0,20)材质应用向上偏移 20

 

    1. 沿顶点法线膨胀偏移 20

 

    1. 按时间,动态偏移(一般用在植被材质中,模拟风吹草动的效果)

 

 

1.2.10 Ambient occlusion 环境光遮蔽

  1. Ambient occlusion 环境光遮蔽:降低背光面的亮度(范围 0-1)
  2. 光线照射到其它物体表面后,通过反弹再反射到当前物体的背光处(UE5 中使用 Lumen 全局光照系统,照亮物体的背光面)
  3. Ambient occlusion 环境光遮蔽可以改善一些凹陷处的漏光问题,但这是一种比较生硬压低环境光的方式,若要细腻改善背面环境光,需要使用 BentNormal 节点(改变在环境光计算时,凹陷处的法线方向),详见环境法线贴图(使用环境法线贴图,有额外的计算开销和纹理采样开销,一般只用于需要高表现的角色模型身上)

 

 

1.2.11 Pixel Depth Offset 像素深度偏移

  1. 像素点到摄像机的距离称之为深度
  2. 像素深度的偏移不会改变模型本身的位置,只影响前后关系的判断
  3. 一般会将像素深度偏移应用在不同物体的交接处(如:石头和地表,使用一定的像素偏移,使之更加自然融合)

 

 

1.3 材质模版

  • 引擎提供了多套材质模板,为了达到不同材质效果,可以在细节面板下切换不同材质模板
  • 其中最重要的包括:
    • Material Domain 材质域
    • Blend Mode 混合模式
    • Shading Mode 着色模型

 

 

1.3.1 Material Domain 材质域

  1. Material Domain 材质域:指定将材质用于何处

 

  1. 不同的 Material Domain 材质域,渲染方式不同
    • Surface :将材质应用于物体表面,是最常用的材质制作方式
    • Deferred Decal:用于贴花
    • Light Function:可以模拟移动的灯光或投影灯
    • Volume:用于体积雾
    • Post Process:后期材质

 

 

1.3.2 Blend Mode 混合模式

  1. Blend Mode 混合模式:决定了当前绘制的材质如何与背景中已绘制了的内容相混合(默认为 Opaque 不透明)
    1. Opaque 不透明:完全将当前的材质覆盖到背景上
    2. Mask 遮罩:只渲染需要的部分,镂空的部分保留原背景(通过输入 Opacity Mask 不透明蒙版,决定遮掉的部分)

 

    1. Translucent 半透明:保留背景,按特定的比例叠加当前材质

 

    1. 其他模式:均为 Opaque 不透明模式的变种,按一定规则进行前景与背景的融合

 

 

1.3.3 Shading Mode 着色模型

  1. Shading Mode 着色模型:控制材质如何反射入射光
    1. 仅反射
    2. 有投射
    3. 有折射再反射(次表面)
  1. 不同的 Shading Mode 着色模型,可以访问的材质输入不同
    1. 如:选择皮肤常用的 Subsurface Profile 次表面轮廓着色模型,则可以访问curvature 曲率的输入

 

    1. 不同的 Shading Mode 着色模型的常见应用:
    • 透明图层:常应用于 车漆
    • 次表面轮廓:常应用于 皮肤
    • 双面植物:常应用于 树叶、草

 

 

1.4 渲染原理

  1. 指定材质给模型后,搭建场景(如下,一个场景中包含不同的模型和不同的材质,每一个模型的材质都有自己的 Base Color 基础颜色、Metallic 金属度等)

 

  1. 在引擎默认的延迟渲染管线下,
    1. 先将视口中不透明的每个像素的材质信息“收集整理”起来,统一按照 PBR 的方式进行渲染
    • Base Color 基础颜色
    • Metallic 金属度
    • Roughness 粗糙度
    • Specular 高光度
    • Normal 法线
    • Shading Model 着色模型
    • Depth 深度
    • ...

 

    1. 输出两个信息:
    • 结合这些材质数据进行光照输出,并经过了光照计算后的颜色信息
    • 记录的场景深度信息
    • (这两张图的位置关系和内容都完全一样,只不过记录的信息不同)

 

    1. 再收集视口中透明的材质信息,按物体从后向前的顺序逐一渲染
    • 如:场景中 2 个透明物体,先绘制距离远的绿色物体,绘制时,比较绿色物体材质每个像素的深度,是否小于当前背景深度(像素深度<背景深度,则距相机更近,将被绘制出来)
    • 绿色物体的深度不写入 Scene Depth(即:绘制橙色材质时,没有绿色材质的深度信息,只能对比背景的深度信息)
    • 当透明物体重叠时,容易造成排序错乱,且景深效果依赖深度信息,造成效果错误

 

 

二. 半透明材质

2.1 创建半透明材质

  1. 将 Blend Mode 混合模式设置为:Translucent 半透明,并输入不透明度,得到一个最简单的半透明材质(这种半透明材质不带方向性,是开销最低的半透方法之一)

 

  1. 若要调整半透明材质的光照,可以在材质细节面板中选择“Surface TranslucencyVolume 表面半透明体积”的半透明度光照模式:
    1. Volumetric NonDirectional 体积无方向:开销最低的逐像素光照(适用于烟雾或沙尘之类大批量粒子效果)
    2. Volumetric Directional 体积方向:带方向性的体积,逐像素计算光照
    3. Volumetric PerVertex NonDirectional 逐顶点体积无方向:与Volumetric NonDirectional 体积无方向相同,但光照只在顶点上计算,因此像素着色器开销极少
    4. Volumetric PerVertex Directional 逐顶点体积方向:与 Volumetric Directional 体积方向相同,但光照只在顶点上计算,因此像素着色器开销极少
    5. Surface TranslucencyVolume 表面半透明体积:计算较复杂,只支持漫反射光照(适用于玻璃或水面之类的半透明表面)
    6. Surface ForwardShading 表面向前着色:开销最高的半透明光照(一般仅在需要重点表现的玻璃或水面上使用)

 

 

2.2 半透明排序

  1. 假定有 2 个半透明物体,按物体中心点距相机的远近,会先渲染远处的物体,再渲染近处的物体并混合

 

  1. 但由于半透明物体不会写入深度缓存,二者间无法比较深度,造成错误的排序关系

 

  1. 所以半透明排序的意义:让本就在上面/前面的物体,最后渲染
    1. 方法一:设置 Translucency Sort Priority 半透明排序顺序
    • 有明确排序需求时,调整 Translucency Sort Priority 半透明排序优先级(数值越大,优先级越高,不论绿色物体多靠近相机,始终绘制在紫色物体下方)

 

    1. 方法二:利用遮罩模式模拟半透明模式
    • 设置混合模式为 Masked 遮罩,并勾选 Dither Opacity Mask 颤动不透明蒙版,模拟半透明效果
    • 本质还是按照蒙版的方式进行渲染,相当于蒙版每帧都发生变化,利用抗锯齿填补蒙版间空隙(因为遮罩本身有深度信息,所以没有半透明排序问题)
    • 从原理上,使用此方法会产生一些问题:材质噪点、鬼影问题(后方物体移动时产生拖尾)

 

    1. 方法三:允许自定义深度写入
    • 在材质编辑器中,勾选 Allow Custom Depth Writes 允许自定义深度写入,同时,模型上也需要勾选 Render CustomDepth Pass 渲染自定义深度通道

 

    • 通过 Scene Texture 材质节点,获取渲染的自定义深度信息(自定义深度信息,存放的是最靠近相机的深度),并与当前渲染的像素深度对比,如果当前像素离自定义深度较远,则舍弃该像素
    • 使用此方法的缺点:当有多层透明时(如:裙摆材质),则无法显示内层的材质

 

    1. 对于半透明排序问题,最根本的解决方案:光线追踪
    2. UE5 中新加入了 OIT 基于像素的排序(在命令行中输入 OIT 就能看到)

 

 

2.3 半透明材质

  1. 因为在不透明物体全部绘制完后,才开始绘制半透明物体,所以在半透明材质内可以获取背景信息(如:背景颜色、背景深度信息等),使用 Scene Texture 材质节点获取中间信息(如:粗糙度、金属度等)

 

  1. 技术博文推荐:UE4透明材质的理解和应用

 

  1. 半透明材质总结:
    1. 半透明材质是在渲染了不透明物体后,逐个进行渲染的
    2. 不会写入 Scene Depth 场景深度信息
    3. 在材质编辑器中,半透明材质可以获取背景信息,可以设置光照模式(Lighting Mode 光照计算设置越完整,计算复杂度越高)
    4. 引擎提供了半透明材质与背景的多种混合方式(公式不同,原理一致)
    • Translucent
    • Additive
    • Modulate

 

 

三. 材质效率

  • 随着材质的复杂度提升,材质的可读性及可维护性变差,因此需要对材质进行管理和维护

 

 

3.1 简化复杂材质

  1. 母材质、子材质/材质实例
    • 将常用的常量转换为参数暴露出来

 

    • 创建材质实例,以便复用

 

    • 材质实例继承了材质内的所有属性,并且暴露了之前设置好的参数

 

  1. 材质内节点折叠、映射
    • 注释(快捷键 C) / 描述:提高单个材质内的可读性

 

    • 节点折叠/展开:以单独图表的形式存在

 

    • 节点映射:通过中间节点的映射,将大段逻辑移走,以保持主视口清晰易懂

 

    • 一个例子:
    • 将所有的纹理输入为引用节点,利用注释框将纹理统一归位,在材质主要操作界面中,使用引用节点代替纹理,占用面积更小
    • 折叠了一些容易引起混乱的数学计算

 

  1. 材质函数
    • 创建材质函数

 

    • 所有材质均可调用材质函数(引擎中内置了大量已经制作好的材质函数)

 

  1. 材质层:使用一个材质表达多种不同材质(如:一套衣服材质中,包含了宝石材质、棉麻布料、金属材质等)
    1. Material Layer(材质内分层)
    • 利用蒙版线性插值,但材质混乱不直观,不利于后期开发维护

 

    • 利用 Material Attributes Layer 材质属性节点分层独立出来,借助 Blend Material Attributes 混合(与线性插值类似),并在细节面板上勾选使用材质属性,将最终的节点转换为 Attributes

 

    1. Layered Material(专门的材质涂层分层)
    • 创建材质图层资产,材质图层内默认按材质属性的方式进行输出,使用 Material Attributes Layer 材质属性节点,或在 Set Material Attributes 设置材质属性节点中添加信息

 

    • 输入土块需要的信息,并转换为参数

 

    • 创建材质图层混合资产,使用蒙版混合(转换为参数,以便复用)

 

    • 创建材质,添加 Material Attributes Layer 材质属性节点,并在细节面板上勾选使用材质属性

 

    • 右键材质,创建材质实例,设置 2 层材质实例的材质图层

 

 

 

3.2 管理材质系统

  1. 简化复杂材质(如上所述)
    • 母材质、子材质/材质实例
    • 材质内节点折叠、映射
    • 材质函数
    • 材质层
    • Material layer 材质图层
    • Layered material 分层材质

 

  1. 规范命名
    • 尽量做到可以不打开材质,仅凭命名和预览,就能判断材质的用途
    • 减少项目内的重名

 

  1. 利用前缀
    • 材质 M_
    • 材质函数 MF_
    • 材质图层 ML_
    • 材质图层混合 MLB_

 

  1. 利用后缀
    • 材质实例_inst
    • 尽量减少累加数字(如:A_01、A_02、……、A_15、A_16 等,最终变得难以分辨)

 

  • 举个例子:
    • 通过后缀区分材质纹理(漫反射、法线、合成纹理)

 

    • 其母材质使用了材质属性,并将复杂的交叉连线折叠到材质函数中

 

 

3.3 查看材质效率

  1. 影响材质效率的因素:
    1. Shader Compile 时长
    • 运算指令数
    • 材质变种

 

    1. 占用硬盘空间大小
    • 材质变种

 

    1. 运行效率
    • 运算指令
    • 半透明层数

 

    1. 材质运算指令数
    • 复杂的数学运算
    • 复杂的光照模型
    • 分层材质导致的额外运算

 

    1. 半透明的开销
    • 层数
    • 运算指令
    • 层数*运算指令,导致的开销高

 

    1. 材质变种
    • Usage 勾选的较多
    • 过多的材质开关

 

 

  1. 引擎中如何查看材质效率:
    1. 检查运算指令数
    • 材质实例左上角检查运算指令数

 

    • 材质下方检查运算指令数及平台数据

 

    1. 材质变种
    • 在细节下查看用途(勾选越多,变种生成就越多)

 

    • 静态材质开关对应 2 个分支,会产生新的材质变种

 

    • 通过材质分析器,分析某个材质静态开关的使用数量及必要性,以减少静态开关的数量,减少材质变种

 

    1. 半透明开销
    • 一般场景材质的开销在 100-200 左右的指令数,精美角色材质的开销在 300 左右的指令数
    • 若半透明大批量应用(如:粒子),需要简化其材质,控制层叠数量,
    • 通过“四边形过度绘制”查看半透明层叠数量(越白,绘制的半透明层数越多)

 

    • 通过“着色器复杂度和四边形”查看整体效果(越白,材质越复杂)

 

 

3.4 材质节点及函数

  1. 常用材质节点及函数

 

  1. 特殊材质节点及函数

 

 

2.5 二次元卡通渲染逻辑

基础来源逻辑:光照与法线方向的点乘,通过色调映射等获得厚涂效果

 

标签:法线,07,物体,深度,UE,材质,Epic,节点,半透明
From: https://www.cnblogs.com/ZWJ-zwj/p/18104752

相关文章

  • 使用vue2实现在线创建组件的功能
    前言我们使用vue2构建了一个项目,项目有个需求:用户可以在线创建vue组件,创建后的组件可以动态编译,项目无需重新部署,就可以在表单等位置引入使用组件。实现记录引用vue的esm包项目中引入vue的代码,原来是importVuefrom'vue'改为importVuefrom'vue/dist/vue.esm'vue.c......
  • 2024年3月29日-UE5-播放特效、自制特效,发射冰球,销毁actor
    打开特效文件夹 选中要添加的特效,然后切换到蓝色子弹的蓝图里,点添加 然后改名为粒子,再创建一个碰撞球体组件 缩放改为0.2 在碰撞球体里面,添加一个碰撞的查询,会打印出发生碰撞的单位 然后返回到主角的蓝图,在创建子弹里,调整下发射点,让主角本身和子弹不重叠 再把球......
  • UE4 C++ Widget的NativeConstruct 与 NativePreConstruct
    构造函数由于Widget是由UE的反射系统创建的,其生命周期由UE引擎管理,所以并不存在构造函数,UE为Widget类定义了两个虚函数NativeConstruct与NativePreConstruct来充当构造函数的作用。而这两个函数的调用都必须在Widget被实例化之后才能进行调用如何在Widget中获取角色在蓝图节......
  • Node+Vue毕设音乐制作资源分享网站(程序+mysql+Express)
    本系统(程序+源码)带文档lw万字以上 文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:在音乐创作和制作的领域,资源的获取与分享一直是创作者们非常关注的话题。随着互联网的普及与发展,人们越来越倾向于通过网络平台交流思想、分享作品以及寻找......
  • Node+Vue毕设音乐推荐网站(程序+mysql+Express)
    本系统(程序+源码)带文档lw万字以上 文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:在当今信息化时代,音乐已经成为人们生活中的重要元素之一。随着互联网技术的不断发展,人们对于音乐的消费方式也在发生着翻天覆地的变化。传统的音乐传播方式......
  • 双端队列Deque——ArrayDeque的实现
    Deque接口表示一个双端队列(DoubleEndedQueue),允许在队列的首尾两端操作,所以既能实现队列行为,也能实现栈行为。Deque常用的两种实现ArrayDeque和LinkedList,这篇主要介绍下Deque的常用操作,并重点看下ArrayDeque的实现逻辑。1、接口API1.1、Queue接口Queue的API......
  • vue3动态加载组件
    Vue2项目中使用require.context()来动态地加载模块。但是Vue3项目默认使用ES模块,而不是CommonJS模块。因此,你不能直接使用require()来加载模块。在Vue3项目中,你可以使用import.meta.glob()或import.meta.globEager()来实现类似的功能。以下是一个例子,如何使用import.meta.gl......
  • vue2,3拖拽组件
    vue3//[email protected]//dom<template><Draggablev-model="list.data"class="drag-container"><template#item="{element}"><div>{{element.name}}</div>......
  • vuex.esm.js:135 Uncaught Error: [vuex] getters should be function but “getters.
    报错vuex.esm.js:135UncaughtError:[vuex]gettersshouldbefunctionbut"getters.mode"inmodule"userModule"is"dark".atassert(vuex.esm.js:135:1)原因:在使用vuex的moulds时index.js中已创建了一个vue实例newVuex.Store,在模块文件中又再创建了一个,导致报......
  • vue3批量将图片添加水印并导出压缩包
    vue3批量将图片添加水印并导出压缩包<scriptsetuplang="ts">import{ref,onMounted}from'vue'importJSZipfrom'jszip'constimg_list=ref([{img:'https://img.keaitupian.cn/uploads/2020/07/20/zv2owzexj5i.jpg'},......