UE5.8 Substrate卡通渲染实战:BSDF组合与风格化材质实现
2026/9/2 14:39:50 网站建设 项目流程

之前在业务开发里用 UE 做卡通渲染,最常见的情况是:要么去改引擎自带的 Shading Model,要么堆一堆 Custom 节点强行把光照响应掰成想要的效果。每次换一个美术风格,都要重写一遍材质逻辑,维护成本很高。后来 Substrate 架构逐步完善,我才意识到,卡通渲染这件事在材质表达层面终于有了更合理的解法。这篇内容我会围绕 UE 5.8 中 Substrate 的核心思路,拆解一个完整的卡通渲染着色器实现过程,并整理实际开发中容易踩的坑和工程化建议。如果你正在研究 Substrate,或者想在 UE 中落地二次元渲染风格,这篇文章应该能帮你省不少时间。

1. Substrate 给卡通渲染带来的变化

1.1 老方案做卡通渲染为什么难受

在 Substrate 之前,UE 的材质系统有一个非常核心的设定:一个材质只能选择一个 Shading Model。默认光照、无光照、Clear Coat、Subsurface、Toon……这些是并列的枚举选项。你选择 DefaultLit,那么整个材质的漫反射、高光、反射基本都是 PBR 物理模型在计算;你选择 Toon,又要去面对 UE 内置卡通模型不够灵活、自定义空间有限的问题。

想要做一款风格化很强的游戏,比如《原神》《崩坏:星穹铁道》那种二次元渲染效果,美术和 TA 通常会走两条路:

  1. 在材质图里用 Custom 节点写一套自己的光照计算,然后把最终颜色输出到 Emissive 通道,配合 Unlit Shading Model 使用。
  2. 直接改引擎的 Shading Model 源码,添加一个自定义光照模型。

第一种方案的问题在于:把漫反射、高光、阴影、边缘光全部塞进 Custom 节点后,材质实例无法很好地暴露参数。更麻烦的是,Custom 节点对平台兼容性、DX 11 / DX12 / Mobile 的支持状态各不相同,遇到有些渲染特性你就只能自己解决。第二种方案的问题是:需要维护引擎源码分支,引擎一升级,代码合并就是一场灾难。

所以长期以来,UE 的材质系统对“非物理渲染”的开发者并不友好。卡通渲染恰恰又是最不需要物理正确、最需要自定义的那一类。

1.2 Substrate 是什么

Substrate 是 UE 自 5.4 开始逐步引入的新材质系统,到了 5.8 阶段已经更加成熟。它的核心变化是:把材质从“一个 Shading Model 枚举”改成“一组可组合、可混合的 BSDF Slab”。

关于 BSDF,简单说一下:Bidirectional Scattering Distribution Function,双向散射分布函数,描述的是光线照射到表面后如何被散射。PBR 里常见的漫反射模型、高光模型,本质上都是 BSDF 的不同组成部分。

在 Substrate 的表达里,你可以把材质理解成一个节点树:

  • 基础漫反射是一个 Slab。
  • 高光反射是另一个 Slab。
  • 次表面散射可能是第三个 Slab。
  • 之后再用 Substrate Mix 之类的节点把这些 Slab 按权重混合起来。

也就是说,材质不再是“从预设模型里选一个”,而是“用 BSDF 基础模块搭一个”。这样做的好处非常明显:

  • 可以做真正的材质分层,比如角色衣服的布料层和皮革层。
  • 可以在材质层面对光照响应做精确控制。
  • 可以结合运行时参数灵活切换不同渲染风格。

对于卡通渲染来说,这意味着你可以自己搭建一套非物理的 BRDF 响应,而不需要去动引擎源码。

1.3 Substrate 让卡通渲染的写法发生什么变化

用旧系统做卡通渲染时,整个流程是:“选择 Unlit → 在 Custom 节点里自己写全部光照 → 输出到 Emissive”。在这个流程里,你放弃了引擎的阴影、光照和反射体系,需要自己取光照方向、计算阴影、处理多光源。

而 Substrate 并不要求你放弃光照体系。相反,它允许你在自定义 BSDF 的同时,保留引擎的光照、阴影、间接光等基础设施。你可以把卡通漫反射看作一个自定义的 diffuse lobe,把卡通高光看作一个自定义的 specular lobe,两者组合成一个 Substrate 材质。这样材质就还能正常接收阴影、参与深度渲染、使用动态全局光照。

这是写法和思路上一个很大的转变:从“绕过引擎的光照模型”到“自定义光照模型的组成部分”。有了 Substrate,做风格化渲染更像是在搭积木。

2. 环境准备与版本说明

2.1 引擎与运行环境

本文的示例基于 UE 5.8 版本。为了尽可能贴近实际项目,建议使用源码版引擎,因为 Substrate 相关的开发和调试通常需要重新编译引擎或查看引擎源码。

推荐环境如下:

项目建议
引擎版本UE 5.8(源码版优先)
操作系统Windows 10/11 或 macOS(取决于目标平台)
开发语言C++ 与 HLSL 结合
图形 APIDX11 / DX12(PC),Vulkan(移动端)
IDEVisual Studio 2022 或 Rider
目标平台PC、移动端或主机,按项目需求

如果你使用的是 Epic Launcher 安装的二进制版,Substrate 相关功能通常也已经包含在内,只是源码调试不如源码版方便。这一点按你自己的实际情况选择即可。

2.2 开启 Substrate

在 UE 5.8 中,Substrate 的启用方式在不同版本中可能略有差异。常见做法是:

  1. 打开项目设置。
  2. 搜索 “Substrate” 或 “Shading Model” 相关选项。
  3. 确保 Substrate 处于启用状态。

有些版本是在 Plugins 中启用,有些则通过控制台变量运行。示例中可能用到的控制台变量:

r.Substrate.Enabled=1

注意,具体选项名称、插件名和默认开关状态可能随引擎版本变化。如果你在打开项目后无法创建 Substrate Material,优先排查这一步。

2.3 关于版本差异的提醒

Substrate 是一个仍在快速演进的系统。UE 5.4 刚推出时很多节点还不够稳定,到了 5.8,整体架构已经更完整,但节点名称、输出类型和部分行为仍有可能在不同版本间调整。

因此本文更重点的是讲实现思路和连接逻辑。如果你在实际操作时发现某个节点名称与文章不同,请优先在材质编辑器中通过搜索关键词找到对应节点,而不是照搬旧版本截图。

3. Substrate 核心概念拆解

3.1 从 Shading Model 到 BSDF Slab

Substrate 最重要的思维转换,是把“材质类型”变成“材质成分”。

旧系统的材质类型是单一的。你无法在一张材质里说“这部分是皮肤,那部分是衣服材质”。但 Substrate 允许你通过 BSDF Slab 组合出混合材质。

所谓 Slab,可以理解为一个“材质层”。每个 Slab 至少包含:

  • 漫反射或次表面等散射信息。
  • 微表面高光信息。
  • 光泽度、粗糙度、各向异性等参数。

多个 Slab 之间可以通过混合节点组合,形成复杂的材质效果。这种思路与真实世界中“一层漆底下有一层金属”的物理结构更接近。

对于卡通渲染,我们不一定需要使用完整的 Slab,因为卡通渲染的物理正确性要求不高。但我们可以利用这种组合能力,把更符合风格化的“自定义漫反射”和“自定义高光”组织起来。

3.2 常用节点与材质输出

在 Substrate 材质编辑器中,典型节点有:

节点作用
Substrate Material材质主输出节点,替代原来的 Material 输出
Substrate Slab创建一个 BSDF 层,可设置漫反射、高光、次表面等属性
Substrate Mix按权重或遮罩混合多个 Slab
Substrate Front Material创建前置材质层,常用于细节覆盖
Custom自定义 HLSL 计算节点,可做风格化光照计算

实际操作中,通常会先在 Custom 节点里计算卡通光照需要的标量和颜色,再把这些值输入到 Substrate Slab 的 Base Color、Roughness 等端口,最后通过 Substrate Material 输出。

需要说明的是,Substrate Material 输出节点与旧 Material 输出节点的引脚有较大差异。创建材质时,你需要在材质属性中把“Material Domain”设置为 Surface,并选择 Substrate 相关选项,否则无法添加 Substrate 节点。

3.3 卡通渲染要处理的三个核心问题

无论引擎怎么演进,卡通渲染最终都要解决三个问题:

  1. 漫反射色调分级。
  2. 高光的风格化控制。
  3. 轮廓线 / 描边。

3.3.1 色调分级

卡通渲染的漫反射不会像 PBR 那样连续渐变,而是会呈现出明显的“台阶感”。通常的做法是把 NdotL 的值映射到几个离散的亮度等级:

  • 亮部。
  • 暗部。
  • 过渡区域可加入渐变贴图控制。

3.3.2 风格化高光

卡通高光通常是区域明显的、边缘锐利的色块,而不是物理真实的 Blinn-Phong 高通带。可以通过控制高光阈值、加上高光形状贴图来实现。

3.3.3 描边

描边方案非常多。常见的有:

  • 背面膨胀法:将模型背面沿法线方向扩展,然后渲染成黑色或自定义颜色。
  • 后处理描边:基于深度和法线差异提取轮廓。
  • 多 Pass 描边:在材质中增加一个轮廓 Pass。

Substrate 主要用于解决材质层面的光照表达,描边通常还需要配合模型或后处理方案。接下来我们先看材质主体部分。

4. Substrate 卡通渲染材质实战

4.1 创建 Substrate 材质资产

在 Content Browser 中右键,选择 “Material”,命名为M_Toon_Substrate

打开材质编辑器后,在材质属性中需要确认:

  1. Material Domain:Surface。
  2. Shading Model:这里不能只选 Toon,而是要选择 Substrate 相关选项。
  3. 混合模式:Opaque。
  4. 光照模式:可以选择 Forward Shading,如果项目是移动端或 PC Forward。

注意,不同版本的 Shading Model 下拉框中,Substrate 相关选项的命名可能不同,但通常带有 “Substrate” 字样。

创建完成后,你会发现默认输出节点是 Substrate Material,而不是旧的 Material 结果节点。

4.2 卡通漫反射:色调分级核心

在 Substrate 材质中,我们仍然可以写 HLSL。先在材质图中创建一个 Custom 节点,命名为CustomToonDiffuse

这个节点的作用是根据法线、光照方向和阴影遮罩,计算一个“分级后”的漫反射亮度。

输入引脚我们规划为:

输入名类型说明
NVector3世界空间法线
LVector3主光源方向
LightMaskScalar实时阴影遮罩
StepsScalar分级档数
ShadowThresholdScalar阴影阈值

输出引脚类型为 Scalar。

核心 HLSL 代码如下,这段代码写在 Custom 节点的 Custom Expression 中:

float ndl = saturate(dot(normalize(N), normalize(L))); ndl *= LightMask; // 将 NdotL 映射到台阶离散值 float toonDiffuse = floor(ndl * Steps) / Steps; // 当台阶值过低时,直接压到阴影阈值之下,产生更干净的卡通阴影 if (toonDiffuse < ShadowThreshold) { toonDiffuse = 0.0; } return toonDiffuse;

这段逻辑很好理解:

  • dot(N, L)得到漫反射强度。
  • 乘以阴影遮罩,让实时阴影参与到分级中。
  • floor将连续值分档,比如 Steps 为 3 时,结果是 0、0.333、0.666、1.0 四档。

不过这里有一个值得注意的点:如果你希望阴影过渡更柔和,不要使用 if 截断,可以把ShadowThreshold也参与一个 smoothstep 计算。因为 if 在 GPU 上会产生分支,影响性能。

更推荐的做法是:

float toonDiffuse = floor(ndl * Steps) / Steps; float shadowMask = smoothstep(0.0, ShadowThreshold, toonDiffuse); return toonDiffuse * shadowMask;

这样既保留了台阶感,又让阴影边缘可控。

在实际项目中,我们通常不会直接使用纯计算出来的灰度值,而是把这个值作为 UV 去采样一张 Ramp 贴图。这样梯度过渡会更有美术表现力。

4.3 卡通高光

卡通高光同样可以用 Custom 节点实现。创建节点CustomToonSpecular

输入引脚:

输入名类型说明
NVector3世界空间法线
LVector3光源方向
VVector3视线方向
SpecularSizeScalar高光范围
SpecularIntensityScalar高光强度

HLSL 如下:

float3 H = normalize(normalize(L) + normalize(V)); float ndh = saturate(dot(normalize(N), H)); // 使用 step 形成硬边高光,实际项目可改成 smoothstep float specular = step(1.0 - SpecularSize, ndh); specular *= SpecularIntensity; return specular;

对于一些二次元渲染,高光形状可能不是简单的圆形。这时可以把高光结果乘以一张高光形状贴图,或者通过另一张 Mask 贴图来控制高光区域的位置。

卡通高光最重要的是“控制边缘锐利度”。如果SpecularSize是 0.1,那么只有 ndh 大于 0.9 的区域才会出现高光。这个方式虽然简单,但非常实用。

4.4 描边与轮廓线

描边不属于材质主体计算,但它是卡通渲染完整效果的关键一环。这里介绍项目中常用的背面膨胀法。

思路是:模型渲染两遍。

  • 第一遍:正常渲染角色的材质。
  • 第二遍:将背面多边形沿法线方向外扩,输出纯色。

想实现这个方法,可以在 UE 中用第二个材质,也可以在同一材质中通过 Pass 或 Custom 实现。不过对于大多数项目,更推荐在建模阶段或者使用后期处理实现描边。

如果使用背面膨胀法,描边材质一般是这样:

// 顶点Shader中的膨胀逻辑 float3 worldNormal = normalize(mul((float3x3)unity_WorldToObject, v.normal)); float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; worldPos += worldNormal * _OutlineWidth; o.pos = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));

注意,在 UE 中你需要通过材质编辑器里的 World Position Offset 引脚来膨胀顶点,而不是直接修改顶点位置的矩阵。这也是 UE 与 Unity 写法上比较大的差异。

4.5 节点连接与材质参数总览

在 UE 5.8 的 Substrate 材质图中,比较推荐的一种连接方式是:

  1. 先用 CustomToonDiffuse 计算漫反射灰度。
  2. 用这个灰度作为 UV 或混合因子,采样一张 Ramp 贴图,得到风格化 BaseColor。
  3. 将 Ramp 颜色连接到 Substrate Slab 的 Base Color / 漫反射引脚。
  4. 将 CustomToonSpecular 结果乘上一个颜色,连接到高光引脚。
  5. 把 Substrate Slab 输出到 Substrate Material。

因此整个材质图的逻辑是:

CustomToonDiffuse -> Ramp 采样 -> Substrate Slab.BaseColor CustomToonSpecular -> 高光颜色 -> Substrate Slab.Specular Substrate Slab -> Substrate Material

为了让这个结构可以被复用,建议把 Ramp 采样和 Custom 节点整理进同一个 Material Function,例如命名为MF_ToonLighting。这样角色、道具都可以复用同一个光照函数。

最终参数建议集中到一个材质实例中,比如:

参数名说明
Steps漫反射分级档数
ShadowThreshold阴影阈值
RampMap渐变色带贴图
SpecularSize高光范围
SpecularColor高光颜色
OutlineWidth描边宽度
OutlineColor描边颜色

这里核心是让 TA 或美术在不进入材质编辑器的情况下,也能调整渲染风格。

5. 常见问题与排查思路

Substrate 在实际落地时,有一些高频问题。下面这张表可以帮你快速定位。

问题现象常见原因解决思路
无法创建 Substrate 材质项目未启用 Substrate 或 Shading Model 不正确在项目设置中确认 Substrate 开关,将材质 Shading Model 切换为 Substrate
材质显示全黑Custom 节点 HLSL 报错,或引脚类型不匹配打开 Material 的 Preview 查看错误,检查输入引脚是否均为 Vector3 / Scalar
Custom 节点在移动端失效Custom 节点 HLSL 在移动后端不受支持使用材质编辑器中的节点组合替代部分逻辑,或为移动端单独做材质资产
卡通阴影有噪点NdotL 直接做了硬阈值,阴影贴图本身有锯齿增加阴影贴图分辨率,或使用 PCSS 等软阴影方案,并配合 smoothstep 过渡
高光过曝或不显示高光数值计算错误,或 V 向量未归一化检查 normalize,确认 SpecularSize 没有设置成负数
描边膨胀后模型穿帮顶点法线或膨胀系数使用不当调整 OutlineWidth,并确认法线是从模型空间转世界空间
Substrate Slab 混合结果不符合预期多个 Slab 的权重、遮罩设置冲突先用纯色遮罩调试每个 Slab 的独立效果

5.1 典型排错过程:材质全黑

如果你创建好 Substrate 材质后,预览窗口一片黑,先不要怀疑引擎。

按这个顺序排查:

  1. 检查 Substrate Material 节点是否存在有效引脚连接。
  2. 检查 Custom 节点内部 HLSL 是否包含字段拼写错误。
  3. 检查输入引脚名称是否与 HLSL 中使用的变量一致。Custom 节点里默认会生成Inputs参数,但有的版本直接用引脚名,需要你在代码里写成对应变量名。
  4. 查看材质编辑器底部的编译日志,关注和 "Substrate"、"HLSL" 相关的报错信息。

大部分全黑问题都是 HLSL 参数引用不一致导致的。尤其是在 Custom 节点中使用多个输入引脚时,建议先在 HLSL 里加上//注释指出每个引脚的用途,便于排查。

6. 最佳实践与工程建议

6.1 把光照逻辑封装成 Material Function

在真实项目中,卡通渲染的材质数量很多,而且不同角色、怪物、道具之间的光照逻辑高度一致。千万不要在每个材质里复制粘贴同一套 Custom 节点。

建议的做法是:

  • 创建一个MF_ToonLighting函数。
  • 把 CustomToonDiffuse、CustomToonSpecular、Ramp 采样全部封装进去。
  • 对外只暴露 Steps、RampMap、SpecularSize 等参数。

这样当光照逻辑需要调整时,只需要修改一个函数,所有引用它的材质自动更新。

6.2 参数规划与材质实例

材质实例是 UE 项目协作的基础。建议把材质参数都设置为可实例化的:

  • 颜色类型用 Linear Color。
  • 数值类型用 Scalar Parameter。
  • 贴图用 Texture2D Parameter。

参数名称建议带前缀,比如Toon_Outline_,便于在大量实例中检索。例如:

Toon_Steps Toon_ShadowThreshold Toon_RampColor Outline_Width Outline_Color

避免在材质图里直接写死数值,否则美术同学每次都要打开材质编辑器才能调整,效率很低。

6.3 平台差异与性能评估

Substrate 虽然灵活,但性能成本仍然要关注。它允许组合多个 BSDF,但这可能增加编译时间和运行时开销。

在移动端,尤其要注意:

  • Custom 节点的 HLSL 写法和支持程度因平台而异。
  • 多 Slab 混合会带来额外计算。
  • 描边 Pass 会增加 Draw Call。

建议在开发初期就确定目标平台,并按平台分级:

  • 高端 PC:使用完整 Substrate 材质,动态阴影、完整描边。
  • 中端手机:减少 Slab 数量,描边改为后处理或用顶点膨胀。
  • 低端手机:可能还需要保留旧材质系统的简化方案。

6.4 升级与兼容性建议

Substrate 仍处于快速迭代期。引擎升级时,材质图里的节点名称、引脚都有可能变化。建议在项目里建立“材质兼容性测试计划”:

  • 每个版本升级后,先打开所有使用 Substrate 的功能材质。
  • 检查 Custom 节点的 HLSL 是否有新的编译警告。
  • 在目标平台上跑一次自动化截图对比。

如果项目使用了引擎源码,升级时优先查看 Substrate 模块的 changelog。这样可以提前知道哪些节点被移除、哪些引脚被合并。

6.5 关于安全与变更流程

这里额外提醒一点:如果在项目里开启了 Substrate,并且在引擎源码层面做了修改,改动前一定要评估生产环境的升级成本和回归范围。所有引擎级改动都应该有版本管理、备份和可回滚方案,不要在没验证的情况下直接应用到正在跑版的项目中。

7. 总结与后续学习方向

在 UE 5.8 中,Substrate 让卡通渲染的实现方式从“改引擎”变成了“组合材质子系统”。对于风格化渲染开发者来说,这是一个非常好的趋势:材质表达更灵活,也能继续复用引擎的光照、阴影和渲染管线能力。

本文主要围绕几个关键点展开:

  1. Substrate 如何改变材质系统:从 Shading Model 枚举转向 BSDF Slab 组合。
  2. 卡通渲染的三大核心问题:漫反射分级、高光控制、描边。
  3. 在 Substrate 材质图中使用 Custom 节点写 HLSL 实现风格化光照。
  4. 工程化管理:用 Material Function 封装逻辑、用材质实例暴露参数、按平台做性能分级。

如果你正准备在自己的项目里落到 Substrate,建议不要一上来就重构所有材质。可以先挑一个主角角色,做一个最小可用的卡通渲染材质,跑通整个管线,再考虑批量替换。这样能最快暴露工具链、平台兼容性和性能问题。

下一步你可以在这几个方向继续深入研究:

  • 引擎源码中 Substrate 的实现路径,了解 BSDF Slab 如何被编译到 Shader 中。
  • 结合自定义 Depth/Stencil 实现更灵活的描边效果。
  • 把卡通渲染与顶点动画、表情系统、道具系统组合,形成完整的一体化渲染方案。
  • 在移动端验证 Substrate 材质的真实性能,用 Profile 工具确认 GPU 开销。

希望这份基于 UE 5.8 Substrate 架构的卡通渲染实现解析,能帮你少踩一些坑,更快把风格化渲染落地到自己的项目里。如果你在配置过程中遇到其他奇怪的报错,欢迎按文章里的排查思路一步步拆解,大部分问题都能在材质编辑器的编译日志里找到答案。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询