UE材质基础
什么是材质
定义了场景中对象的表面属性
决定光源是如何与物体表面交互
- 反射——漫反射,镜面反射
- 折射
- 透射
本质上应用于Mesh并控制Mesh的视觉外观
- 固体——塑料,岩石,木板,铁块...
- 次表面——皮肤,树叶,玉石...
- 透明——玻璃,水
基于物理-PBR(Physically Based Rendering)
- 4个基础属性:漫反射,粗糙度,金属度,高光度
- 一个材质可能需要:法线,环境光遮蔽(AO),置换纹理(WPO)...
材质基础
基础颜色
- 对于非金属,代表漫反射信息
- 尽量避免纯黑和纯白
- RGB通道范围为0~1
- 纹理不要带有光影信息
- 使用纹理时,注意材质内纹理采样器应当和纹理本身一致(比如是线性还是sRGB)
粗糙度
- 0~1范围区间,默认为0.5
- 一般会在specular设为0.5的情况下,微调roughness
- “是否光泽”的重要因素
- 在DXT1压缩情况下,一般选用G通道存储粗糙度(精度更高)
高光度
-
仅对非金属(Metallic≠1)有效
-
0~1范围区间,默认为0.5
-
对应的F0是0~0.08,0.5对应的是0.04,可以对于自然界中大多数非金属的F0(不精准)(F0是指在菲涅尔反射中与摄像机视线垂直面的反射率,也就是法线方向的反射率属性)
-
通常情况下不需要调整
-
特殊用法:调低高光度甚至为0,用于屏蔽凹陷等微阴影出的高光
金属度
- 通常为0或者1,默认为0(非金属)
- 为1的时候,只有高光反射,F0为diffuse(基础颜色)
制作材质流程
一般制作一个材质会先定义这个材质是否为金属,并且输入它的基础颜色,然后在高光度为0.5的情况下,去微调粗糙度。在粗糙的的效果比较满意之后,再近一步比较特殊的地方,比如刮痕凹陷处再二次调整金属度和高光度。
Normal
-
通过改变像素与光的交互方向,为模型表面增加细节
-
模型本身多边形并没有发生改变
-
实践中,可以按距离,混合多层法线改善近距离的表现
混合两个法线使用BlendAngleCorrectedNormals:
切线
与法线纹理类似我们可以将切线纹理输入到切线以调整切线的方向。
各项异性
调整高光的形态,决定了高光沿着切线拉伸的范围。
各项异性的范围是0~1,0意味着没有各项异性的效果,高光不会进行拉伸。
-
未使用各项异性
-
使用各项异性
自发光颜色
让材质有一个发光的效果,通常会给一个高于1的值
全局位置偏移
一种针对顶点的形变,一般会用在植被材质中模拟分吹草动的效果。
环境光遮蔽
一个物体的背光面之所以会被照亮是因为光线会打到其它物体的表面进行一个反弹,再反射到当前物体的背光处。
出于艺术表达的角度,要降低背光面的亮度这时就可以用环境光遮蔽。
环境光遮蔽也是0~1的范围,0则没有环境光贡献。
环境光遮蔽可以改善一些凹陷处的漏光问题,但这是一种比较生硬的压低环境光贡献的一种方式,若想更细腻个改善背面环境光的贡献。我们可以使用BentNormal节点,它改变得是在环境光计算是凹陷处的法线方向。
具体查看文档中环境法线贴图的说明,需要注意的是使用环境法线贴图有额外的计算开销和纹理采样开销,一般只会用于需要高表现的角色模型身上。
像素深度偏移
像素点到摄像机的距离称之为深度
-
未偏移
-
进行一定偏移,地板的材质跑到了模型上了一点
像素深度的偏移不会改变模型本身的位置,它只会影响前后关系的判断。一般会将像素深度偏移应用在不同物体的交接处,比如石头和地表使用一定的像素偏移可以使得它们融合更加自然。
混合模式(Blend Mode)
- 当前材质的输出如何与背景中已经绘制的内容进行混合
- 不透明(Opaque):完全将当前的材质覆盖到背景上
- 遮罩(Mask):只渲染需要的部分,镂空的部分保留原背景
- 半透明(Translucent)等:保留背景,按特定的比例叠加当前材质
着色模型(Shading Model)
- 控制材质是如何反射入射光
- 只有反射
- 有透射
- 有折射再反射(次表面)
- ......
- 不同的shading model,可以访问的材质输入不同
材质域(Material Domain)
- 指定将材质用于何处
- 不同的material domain渲染方式不同
- Surface:物体表面,最常用
- Deferred Decal:用于贴花
- Light Function:可以模拟移动的灯光或投影灯
- Volume:用于体积雾
- Post Process:后期材质
渲染的原理
延迟渲染与离线渲染器的差异
- 将视口中不透明的材质信息“收集整理”起来,统一按照PBR的方式进行渲染
- Base Color
- Metallic
- Roughness
- Specular
- Normal
- Shading Model
- Depth
- ......
在这一步骤完成后会输出两个信息,第一个是结合刚才这些材质数据进行光照输出的经过光照计算后的颜色信息。另外一个记录的是深度信息。
这两张图位置关系完全一样,内容也完全一样的。不过记录的信息不同。
- 再将视口中透明的材质信息,将物体从后想前的顺序逐一渲染
- 不写入Scene Depth
- 透明物体重叠的时候,排序错乱
- 景深效果依赖深度信息,可能效果出错
- 不写入Scene Depth
透明材质
创建半透明材质
把模型的材质的混合模式改成半透明,并输入一个不透明度之后,就获得了一个最简单的半透材质,这种半透是不带方向性的,是开销最低的半透方法之一。
如果想调整半透明的的光照,在半透明度那一块中调整它的光照模式
- 体积无方向 将为不带方向性的体积计算光照。适用于烟雾和沙尘之类的粒子效果。这是开销最低的逐像素光照法,然而材质法线并未纳入考量。
- 体积方向 将为带方向性的体积计算光照,是逐像素光照法,因此材质法线纳入考量。
- 逐顶点体积无方向 与体积无方向相同,但光照只在顶点上计算,因此像素着色器开销极少。
- 逐顶点体积方向 与体积方向相同,但光照只在顶点上计算,因此像素着色器开销极少。
- 表面半透明体积 将计算表面的光照。光照被累积在一个体积中,因此结果较为模糊,距离有限,但逐像素开销极低。其适用于用于玻璃或水面之类的半透明表面。只支持漫反射光照。
- 表面向前着色 将计算表面的光照。此项适用于玻璃或水面之类的半透明表面。其以前向着色实现,因此支持来自本地光照的镜面反射高光,但很多仅限延迟的功能并非如此。这是开销最高的半透明光照法,因为每个光照的贡献度均为逐像素计算。
半透明排序问题
如果一个半透物体比另外一个半透物体模型更靠前,那么它的所有像素都会绘制在另一个半透物体前。
方法一 设置半透明排序顺序
如果当前有明确的排序需求,可以调整半透明排序优先级,数值越大优先级越大。
方法二 利用遮罩模式来模拟半透明模式
将混合模式设置为遮罩,再勾选颤动不透明蒙版选线,来达到模拟半透明效果。本质还是按照蒙版的方式进行渲染,但是它的蒙版相当于每一帧在发生变化,利用抗锯齿把蒙版之间的空隙填起来。因为遮罩本身有深度信息,所以不会有半透明排序的问题。
但是这个方法从原理上一些问题是无法规避掉的。比如材质看起来会有噪点,而且还有鬼影问题,有物体在后面拖动有很长的拖尾。
有时会用这种方法来模拟毛发的制作。
方法三 允许自定义深度写入
勾选允许自定义深度写入
再在模型上勾选
然后可以通过Scene Texture节点拿到渲染的自定义深度信息,有了自定义深度信息就可以与当前渲染的像素深度进行对比,自定义深度信息存放的是最靠近我们的深度,如果当前像素离自定义深度比较远我们就不要这个像素。
效果如下
这种方案的缺点也很明显,因为这样看不到第二层的透明了,如果是两层的半透明的裙摆,这样就看不到第二层的裙摆了。
对于半透明排序问题最根本能解决的还是光线追踪,ue5中又加入了OIT(基于像素的排序)。
透明材质小结
- 在渲染不透明物体后,逐个渲染
- 不写入Scene Depth
- 可以获取到背景信息
- 越完整的光照计算设置(lighting mode)的计算复杂度越高
- 有多种与背景的混合方式(公式不同,原理一致)
- Translucent
- Additive
- Modulate
简化复杂的材质
- 母材质,子材质/材质实例
将需要的常量转变为参数,应用之后就可以创建这个材质实例。
材质实例继承了材质的所有属性,并且暴露了设置好的参数。
材质实例化可以更改材质的外观,同时避免材质重复编译。
使用材质实例的方式为不同的模型提供不同的外观。
- 提高材质的可读性
框选住一段材质节点后,按下键盘C添加注释。单个节点可以添加描述。这样看起来更直观。
- 材质内节点折叠,映射
框柱一段节点,右键可以进行折叠。这点后的节点也可以进行重命名和描述增加它的可读性。
双击中间的连线,生成一个小节点,右键小节点,转换为命名重路由。这样就可以把这段节点移动到相对较远的地方,保持主视口清晰易懂。
- 材质函数
想要将一段节点给其他材质用,除了直接复制过去外,还可以创建材质函数,给其他材质调用。
引擎中有很多预制的材质函数,可以供我们调用。
- 材质层
- Material layer 材质图层
- Layered material 分层材质
Layered material 分层材质
我们把每一层的信息利用一个MaterialAttributes相对独立出来,这样会更加直观方便后续维护。
Material layer 材质图层
这种分层方式需要专门的材质图层资产和材质图层混合资产
-
右键内容游览器空白处,创建材质图层
-
在材质图层里,设置好参数
-
右键内容游览器,创建材质图层混合
-
在材质混合中创建遮罩,还可以将它转换为参数方便复用。
-
创建用于材质图层的材质材质基底,并把Material Attributes Layers加进来,并转换为使用材质属性。
-
用材质基底创建材质实例,添加材质层,设置相关资产。
管理材质系统
核心思想:抽离共通逻辑,加强复用。
-
母材质,子材质/材质实例
-
材质内节点折叠,映射
-
材质函数
-
材质层
-
Material layer 材质图层
-
Layered material 分层材质
-
-
规范命名
- 尽量做到可以不打开材质,仅凭命名和预览,就能判断材质的用途
- 减少项目内的重名
-
利用前缀
- 材质M_
- 材质函数MF_
- 材质图层ML_
- 材质图层混合MLB_
-
利用后缀
- 材质实例_inst
- 尽量减少累加数字,A_01,A_02,... ...,A_15,A_16最终变得难以分辨
材质效率
- Shader Compile时长
- 运算指令数
- 材质变种
- 占用硬盘空间大小
- 材质变种
- 运行效率
- 运算指令
- 半透明层数
- 材质运算指令数
- 复杂的数学运算
- 复杂的光照模型
- 分层材质导致的额外运算
- 半透明的开销
- 层数
- 运算指令
- 层数*运算指令导致的开销高
- 材质变种
- Usage勾选
- 过多的材质开关
如何查看数据
点击平台数据,可以看到PC下的运算指令数。
材质变种可以在细节下查看用途,勾选的越多变种生成就越多。
静态材质开关也可以增加变种
工具>审计>材质分析器,来分析每一个材质的静态开关使用数量,以及这些开关是否必须来减少静态开关使用的数量。来减少材质变种。
通过视口,四边形过度绘制来查看,颜色越偏向白绘制的半透明层数越多。
节点
二次元卡通渲染逻辑
以此达到一个厚涂的效果