知识框架(UE5)
知识框架
1. 硬件与图形 API 基础
-
Vulkan、Metal、DirectX 定位与 UE5 的 RHI 抽象
-
Vulkan 和 Metal:
它们是图形驱动 API(接口)。你可以把它们理解为游戏引擎与显卡沟通的“语言”。
-
Vulkan: 由 Khronos 组织开发,主要用于 Android 和 PC。它非常底层,能让开发者直接控制 GPU。
-
Metal: 由 Apple 开发,专门用于 iOS/macOS。它的执行效率极高,是苹果设备的标配。
-
DirectX 是微软 Windows 专属(部分支持 Xbox),Vulkan 是跨平台(Windows、Linux、Android、Switch 等)。
-
特性 DirectX 11 (传统派) DirectX 12 (现代派) 核心理念 高度自动化,“保姆级”封装,易于开发但性能上限受限 底层的“专家模式”,将硬件控制权充分交给开发者,性能潜力巨大 CPU利用率 主要依赖单线程,对多核CPU利用不充分 原生支持多线程,能让所有CPU核心高效工作,减轻瓶颈 性能表现 对不同硬件的兼容性更稳定 在优化得当的情况下,游戏帧率可比DX11提升10%-20% 支持平台 Windows 7及更高版本 Windows 10及更高版本(不支持Windows 7) 前沿技术 基础 支持光线追踪(DirectX Raytracing,让光影更真实)、可变速率着色等画质提升技术 开发难度 较低 较高,需要开发者具备更深的硬件知识 -
RHI (Render Hardware Interface):
它是 UE 的渲染硬件接口层。
-
作用: 它是“翻译官”。UE 写了一套通用的渲染命令,RHI 负责把这些命令翻译成 Vulkan、Metal 或 DirectX 能够识别的指令。
-
硬件对应: 它运行在 CPU 上,但控制着 GPU 的行为。
-
-
-
RHI 与性能监控工具(GPU Profiler、Unreal Insights)
-
设备类型 目标帧率 (FPS) 内存占用 建议性能目标 高端 PC 120+ 不限 开启全动态光影 (Lumen),显存 8GB+ 安卓 (高端) 60 2GB 左右 烘焙光照,使用 RVT,材质指令 < 200 安卓 (低端) 30 800MB 禁用阴影,贴图最大 1024,材质指令 < 100 如何设定:
-
建立 Device Profiles: 在 UE 中针对
Android_Low和Android_High设置不同的纹理上限和渲染等级。 -
性能抓帧: 在目标手机上运行,观察 GPU Time。如果 GPU Time > 33ms,那说明你的画面必须降级(30 帧都稳不住)。
-
Stat Unit 解读
指标 你的数值 解读 Frame 21.54ms (浮动28-30ms) 帧耗时。移动端目标通常是30 FPS(33.3ms)或60 FPS(16.67ms)。 Game 5.69ms 游戏线程耗时(处理蓝图、物理、AI等)。<5ms表示良好,<10ms可接受。 Draw 7.64ms 渲染线程(收集绘制命令)耗时。 RHI 7.30ms RHI线程(将渲染命令翻译为图形API调用)耗时。 GPU Time 20.76ms GPU实际渲染耗时。(如果目标是60 FPS,则超标;如果目标是30 FPS,则处于临界)。 Mem 763.56MB 总内存占用。对移动端偏高,需关注纹理/渲染目标内存。 RenderRes 91.2% (1459x657) 渲染分辨率约为屏幕分辨率的91%,常见且合理。 Draws 303 绘制调用数(CPU提交给GPU的绘制命令)。移动端推荐<500。 Prims 3930.2K 每帧绘制的三角形数量约393万。对于移动端,这个值偏高(通常建议<100万),需优化模型面数或LOD。 -
RHI (Rendering Hardware Interface) 是引擎与显卡之间的桥梁。
-
指令: 在控制台(
~键)输入stat RHI。 -
关键数值:
-
Draw Calls: 显卡要画多少次。移动端建议控制在 200-500 以内。
-
Triangles / Primitives: 画面里三角形的总数。
-
Total GPU Memory: 显存占用。
-
-
意义: 如果 Draw Calls 极高,说明你模型没合批;如果 Primitives 极高,说明你没做 LOD。
-
CPU-GPU 协作:几何图元、Draw Call 概念
-
内存架构:RAM vs VRAM,Cache 层次,数据流转路径
-
内存(RAM)与显存(VRAM)
在 PC 上,内存和显存是分开的。但在手机上,它们是共用一块内存芯片的。
-
PC 架构: 内存(RAM)在主板上,存逻辑;显存(VRAM)在显卡上,存贴图。
-
移动端架构(SoC): 统一内存架构 (Unified Memory)。
-
CPU 和 GPU 共用一块物理内存条。
-
如果你说“贴图占了 2GB”,那这 2GB 就从手机的总 8GB 内存里划走了。这意味着如果贴图过载,系统会直接杀掉游戏进程(崩溃)。
-
-
计算公式:
一个未经压缩的贴图大小为:
Width x Height x 4 bytes (RGBA)}
例如:一张 2K 贴图 (2048x2048) 约为 16MB。
-
内存缓存 (Memory Cache)
-
L1 / L2 / L3 Cache
Cache(缓存) 是为了解决 “CPU 算得太快,而内存搬运太慢” 的问题。
-
L1 (Level 1): 最靠近核心,速度最快(接近 CPU 频率),但容量极小(几十 KB)。像你手里的笔。
-
L2 (Level 2): 速度稍慢,容量稍大(几百 KB 到几 MB)。像你桌上的笔记本。
-
L3 (Level 3): 所有核心共享,容量最大(几十 MB),速度最慢(但仍比内存快得多)。像你书架上的字典。
-
内存 (RAM): 像楼下的图书馆。如果 CPU 去内存拿数据,它得停下来等几百个时钟周期,表现出来的就是游戏卡顿。
2. 渲染管线与资产流转
-
完整渲染管线过程(顶点→像素→帧缓冲)
-
应用阶段 (CPU): 决定谁该被画出来。计算角色的动作、碰撞、UI,最后打包成指令发给 RHI。
-
几何阶段 (GPU):
-
顶点着色器 (VS): 把模型的 3D 坐标转换成屏幕上的 2D 坐标。局部空间 →世界空间: 物体在地图里的位置。世界空间→观察空间: 物体相对于相机的位置。观察空间 →裁剪空间: 利用投影矩阵(Projection Matrix),将 3D 坐标投影到 2D 屏幕区域。
-
裁剪与剔除: 视锥体剔除 (Frustum Culling): CPU 判断物体是否在相机镜头里。不在的直接“砍掉”,不发 Draw Call。 遮挡剔除 (Occlusion Culling): 判断物体是否被前面的大墙挡住了。 背面剔除 (Backface Culling): GPU 在渲染时发现三角形的背面朝着相机,直接不画。。
-
-
光栅化阶段 (GPU): 把三角形连成的几何图形转换成成千上万个“像素点”。原理: GPU 会扫描屏幕上的每一个像素,判断这个像素中心点是否落在某个三角形内部。如果在内部,就给这个像素打个“标签”,准备涂颜色。
-
像素阶段 (GPU):
-
像素着色器 (PS): 计算每个像素点应该是什么颜色。这就是你 872 条指令材质干活的地方。这是计算颜色的步骤。它根据你材质里的逻辑(贴图、光照、If 判断、Power 运算),算出光栅化产生的每一个像素点最终应该是红的还是绿的。
-
-
输出合并: 把透明度混合、深度测试做好,最后把这一帧的画面塞进显示器。
-
原理: GPU 会扫描屏幕上的每一个像素,判断这个像素中心点是否落在某个三角形内部。如果在内部,就给这个像素打个“标签”,准备涂颜色。
-
UV 坐标与纹理映射
-
UV 坐标不是世界坐标。
-
定义: UV 是模型表面上的 2D 坐标系统 ($u, v \in [0, 1]$)。你可以把它想象成把一个纸箱子拆开铺平后的平面坐标。
-
关系:
-
顶点: 模型上的一个点(3D)。
-
UV: 对应这个顶点在贴图上的哪个位置(2D)。
-
-
顶点动画与 UV:
-
顶点动画改变的是顶点的 3D 位置(比如风吹动树叶)。
-
UV 通常是不动的。即使顶点动了,它依然读取贴图上那个点的颜色。
-
-
资产从硬盘到显存的完整路径(.uasset → 内存 → VRAM)
-
渲染管线资产流转图(从硬盘到显示器)
-
硬盘 (SSD): 存储 .uasset 原始数据。
-
内存 (RAM): 当你加载关卡,CPU 把模型结构、逻辑变量调入内存。
-
显存 (VRAM): 贴图、顶点数据被推入显存,等待 GPU 召唤。
-
寄存器/缓存: GPU 运算过程中的临时数据。
-
实时渲染与离线渲染的区别
-
实时渲染: 玩家在安卓手机上操作,GPU 每秒计算 30-60 帧。这时 Draw Call 极度重要,因为 CPU 必须实时告诉 GPU 画什么。Draw Call 高了,手机就卡成幻灯片。
-
离线渲染(视频):电影大片。一帧算 1 小时,极致精度。 只有当你打算把游戏内容做成一段宣传片/开场动画时,才叫离线渲染。渲染完输出的是视频格式。
-
为什么安卓端不用离线渲染? 因为视频没有交互。如果玩家能控制角色走动,那就必须是实时渲染。
-
性能提升: 降低 Draw Call 提升的是 CPU 的分发效率,而不是离线渲染的内存。
-
UE 实现离线渲染: 使用 Movie Render Queue (MRQ)。
-
操作: Window -> Cinematics -> Movie Render Queue。在设置里开启
High Quality ADISON采样,能把场景渲染成真正的电影画质。
ue管线的可编程阶段与固定阶段
1. 可编程阶段 (Programmable Stages)
这些阶段允许开发者编写 HLSL (High-Level Shading Language) 代码。在 UE 中,你通常通过材质编辑器 (Material Editor) 的连线逻辑来间接控制这些阶段。
-
顶点着色器 (Vertex Shader, VS):
-
功能: 处理每一个顶点的位置、法线和切线。
-
UE 中的应用: 材质节点中的 World Position Offset (WPO)。你可以通过它实现旗帜飘动、植被摆动或复杂的顶点动画。
-
-
像素/片元着色器 (Pixel/Fragment Shader, PS):
-
功能: 决定屏幕上每个像素的最终颜色。
-
UE 中的应用: 材质编辑器的大部分逻辑(Base Color, Roughness, Normal, Metallic 等)。这是计算光照、纹理采样和颜色混合的核心区域。
-
-
计算着色器 (Compute Shader, CS):
-
功能: 独立于常规渲染流程的高性能并行计算。
-
UE 中的应用: Niagara 粒子系统的复杂物理模拟、虚拟阴影映射 (VSM) 的剔除、以及后期处理中的某些高级特效。
-
2. 固定功能阶段 (Fixed-Function Stages)
这些是由 GPU 硬件直接完成的物理过程。虽然你可以通过渲染状态(如深度测试开关)来配置它们,但你不能编写逻辑代码来改变它们的工作方式。
-
输入装配 (Input Assembler, IA):
-
功能: 读取缓冲区中的顶点数据(位置、UV、颜色)并组合成几何图元(三角形、线段)。
-
-
光栅化 (Rasterization):
-
功能: 将 3D 空间中的几何体转换为 2D 屏幕上的像素点(片元)。
-
注意: 这是渲染流水线中最典型的“固定”阶段,硬件会自动判断哪些像素被三角形覆盖。
-
-
深度测试与模板测试 (Early-Z / Stencil Test):
-
功能: 决定一个像素是否应该被遮挡。
-
UE 优化: UE 频繁使用 Early-Z Pass,在执行昂贵的像素着色器之前先剔除被遮挡的像素,这属于硬件级的优化。
-
问题:传统深度测试在像素着色器之后进行。那些最终被挡住的像素仍然跑完了昂贵的像素着色器,浪费性能。
Early-Z:在像素着色器之前就执行深度测试,直接丢掉会被遮挡的像素。
特性 传统深度测试 Early-Z 执行时机 像素着色器之后 像素着色器之前 能否丢弃被挡像素 可以,但已浪费着色器计算 可以,并且避免无用的着色 性能 低(浪费) 高(节约) 限制 无 如果像素着色器修改深度值(如discard、深度写入),Early-Z失效
-
-
输出合并 (Output Merger):
-
功能: 将计算出的像素颜色与当前的渲染目标(RenderTarget)进行混合,并处理 Alpha Blending(半透明混合)。
-
3. UE 特有的逻辑划分
由于 UE 是一套高度抽象的引擎,它在标准管线之上增加了自己的逻辑层:
| 阶段 | 类型 | 描述 |
| Nanite 虚拟几何体 | 半可编程 | 使用计算着色器 (CS) 代替了传统的光栅化逻辑,实现了极高面数的渲染。 |
| Material Instance | 配置化 | 通过参数化控制可编程阶段,而无需重新编译 Shader。 |
| RHI (Rendering Hardware Interface) | 中间层 | 负责将 UE 的渲染指令翻译给具体的硬件 API(如 DX12 变为硬件指令)。 |
-
顶点 / 像素着色器中的运算
Shader 里凡是用到ScalarParameter的地方,实际是一个uniform float。
改变实例里的数值 → 更新 uniform → 着色器内部的乘法、Lerp、分支条件等计算结果发生变化,但指令序列不变。 -
纹理采样
TextureSampleParameter允许实例换一张贴图 → 只需绑定不同的 SRV(Shader Resource View),同样不触发重编译。 -
静态开关参数(Static Switch)—— 特殊情况
这种参数会真正改变 Shader 代码(比如去掉一大段指令)。
但 UE 会为每个开关组合预编译出独立的 Shader 变体。
实例选择不同的开关状态时,只是切换到另一个已编译好的变体,不会发生运行时的实时编译。
3. 纹理与材质(TA 的重头戏)
3.1 纹理核心概念
-
Mipmap、纹理术语(Albedo、Normal、Roughness 等)
-
Mipmap (多级渐远纹理)
-
开启方法: 双击贴图进入编辑器,在右侧搜索
Mip Gen Settings,通常选FromTextureGroup即可。 -
原理: 引擎会预先生成不同尺寸的缩略图。远处的物体用小图,既省显存又能减少画面闪烁(走样)。
-
Mipmap 是一组预计算的纹理序列,每一级的分辨率都是前一级的 1/2。比如一张 1024x1024 的图,它的 Mip 链包含 512、256、128……直到 1x1。
-
工作原理: 当 GPU 渲染物体时,它会计算该物体在屏幕上占据了多少个像素(Pixel)。如果一个远处的油漆桶在屏幕上只占 10 个像素,GPU 就不会去读取那张 1024 像素的大图(那太浪费带宽了),而是直接抓取 Mip 链中对应大小的小图(比如 16x16)。
-
为什么要用它?
-
性能(带宽): 显卡读取的数据变少了,总线压力变小。
-
抗锯齿(Moiré Patterns): 如果没有 Mipmap,当高分辨率纹理在远距离渲染时,像素点会跳跃,产生闪烁和类似“摩尔纹”的噪点。
-
-
空间换时间: 开启 Mipmap 会增加约 33.3% 的磁盘和显存占用。但在移动端,这 33% 的空间支出是绝对超值的,因为它换回了帧率的稳定。
-
PBR纹理术语速查表
术语 通俗理解 黑/白代表什么 常见后缀 Albedo(固有色) 物体本来的颜色,不受光照影响。就像一张彩色照片,没有阴影和高光。 无黑白含义,就是RGB颜色 _D,_BaseColor,_AlbedoNormal(法线贴图) 欺骗眼睛的“假凹凸”。通过改变表面光线反射角度,让低模看起来有高模的细节(如砖缝、铆钉)。 法线向量存在纹理中,呈蓝紫色(非黑白) _N,_NormalRoughness(粗糙度) 表面是光滑还是粗糙。反光越糊、越分散 → 表面越粗糙。 白=粗糙(磨砂、石头)
黑=光滑(镜子、金属)_R,_RoughnessMetallic(金属度) 区分金属与非金属。金属反光带自身颜色,非金属反光为白色。 白=金属(铁、金)
黑=非金属(木头、塑料)_M,_MetallicAO(环境光遮蔽) 预制的“暗角”,模拟缝隙、角落中光线难以进入产生的阴影,增加立体感。 白=无遮挡(开放区域)
黑=完全遮挡(缝隙深处)_AO,_OcclusionHeight / Displacement 真正的凹凸,会移动顶点位置或视差偏移,产生立体感(代价大)。 白=凸起
黑=凹陷_H,_Height,_DispEmissive(自发光) 物体自己发光,不受场景光照影响,甚至能照亮周围。 无黑白含义,就是RGB颜色(亮度可超出1) _E,_Emissive
📌 一句话记住它们的作用关系
Albedo 给颜色,Normal 骗凹凸,Roughness 定光滑,Metallic 分金属,AO 加暗角。
-
法线贴图格式:DX(Y-) vs OpenGL(Y+)
-
DX (DirectX): 绿通道反向。
-
GL (OpenGL): 正常。
-
识别: 如果你发现法线在场景里看起来凹凸反了(灯光照上去怪怪的),双击贴图,勾选
Flip Green Channel就能解决。 -
贴图优劣标准与跨平台分配策略
-
贴图优良差的标准:
-
优: 尺寸为 2 的幂次方(如 512, 1024);使用了压缩格式(PC 用 BC7,安卓用 ASTC,iOS 用 PVRTC);采样器数量少。
-
差: 奇数尺寸;使用了过多的 Alpha 通道(透明);未开启 Mipmaps(导致远处闪烁且浪费性能)。
-
在
Project Settings -> Device Profiles中。 -
你可以为
Android_High设置贴图最大分辨率为 2048,为Android_Low设置为 512。 -
引擎会自动根据设备性能,在加载时对贴图进行截断(Clamp)。
-
纹理资源: 硬盘上的 .png / .tga 文件。
-
纹理对象: 贴图本身作为一种参数被传递(常用于材质函数内部)。
-
纹理采样: 一个动作。GPU 去贴图里查“这个点的颜色是什么”。
3.2 材质逻辑与性能
-
材质域(Material Domain):Surface、Deferred Decal、Post Process 等,决定材质节点链的最终用途
-
材质域告诉 GPU 这个着色器应该在渲染管线的哪一步运行。
-
Surface (表面): 默认模式。用于所有实型物体(草、石头、人)。受光照影响。
-
Deferred Decal (延迟贴花): 像贴纸一样贴在别的物体上。
-
注意: 贴花过多会导致 Overdraw。层叠多了会导致材质复杂度变白。
-
-
Post Process (后处理):它在整个画面渲染完后,对屏幕像素进行二次计算(如全屏雪花、色调调节)
-
混合模式(Blend Mode):
-
Opaque(不透明,性能最优)
-
Masked(带透明裁剪,Alpha Test 开销)
-
Translucent(半透明,开销最大,涉及排序和 Overdraw)
-
-
材质三兄弟(MF / MID / MPC):
-
材质函数(MF):黑盒封装,复用节点网络
-
动态材质实例(MID):运行时修改参数,避免材质编译
-
材质参数集(MPC):全局控制多材质参数
-
概念 类比 作用范围 性能/特性 Material Parameter Collection (MPC) 广播站 全局。修改一个值,场景内所有引用它的材质都会同步改变。 极高。CPU 只发一次指令,GPU 批量更新。适合做雨雪、昼夜、全局风力。 Dynamic Material Instance (DMI) 私人电话 实例级。每个物体可以有独特的值(如:这个怪血多,那个怪血少)。 中等。每个物体都要单独通信。必须在蓝图/C++ 中创建并赋值。 材质参数 (Scalar/Vector Param) 变量名 基础单元。它是 MPC 或 DMI 里被修改的具体那个“名字”。 只是一个槽位,本身不决定性能。
-
-
Alpha 透明性能开销与通道打包技术
-
具体含义: 不只是半透明。
-
Masked (遮罩): 比如树叶,虽然不是透明,但有镂空。这会导致 Overdraw (过度绘制),即显卡在同一个像素点上画了好几次,性能消耗极大。
-
移动端准则: 能用几何体切出来的形状,别用 Alpha 贴图抠。
-
Alpha 通道与性能:隐藏的“隐形杀手”
A. Alpha 通道占用的性能逻辑
纹理在内存中的存储是按通道算的:
-
RGB 纹理: 占用 3 个 8-bit 通道(24 位/像素)。
-
RGBA 纹理: 占用 4 个 8-bit 通道(32 位/像素)。 结论: 只要你带了 Alpha 通道,显存占用直接增加 33%。在移动端带宽极其有限的情况下,这会导致 GPU 读取纹理变慢。
-
B. 合并 Alpha 到 BaseColor 的利弊
Wit 的友情纠正: 不要单纯为了“减少纹理数量”就把所有东西往一张 4K 贴图里塞。合并 Alpha 后的 BaseColor 如果变成了 4K,而你原本的 Alpha 只需要 512 的清晰度,那你反而浪费了大量的内存空间。匹配分辨率优先级 才是高手的基操。
C. 终极优化建议:通道打包 (Channel Packing)
-
Masked 材质在移动端的优化方法
Masked 材质开销较大,可以做以下优化:
-
改用 Opaque + 模型裁剪:如果物体形状固定,将 Mask 效果直接做进模型(几何体裁剪)。
-
减少 Overdraw:控制 Mask 区域不要过于细碎。
-
降低分辨率:降低 Mask 纹理分辨率,并使用高质量采样。
-
针对移动端使用 Simple Shader:避免复杂的光照计算。
-
匹配分辨率优先级
这是一个美术资源管理的“潜规则”:
在职业开发中,我们通常不只是合并 Alpha。我们会进行 RGBA 全填充:
-
逻辑: 并不是所有贴图都要一样大。
-
优先级排序:
-
最高(4K/2K): 玩家视线正前方的地板、主角的脸、武器。
-
中等(1K/512): 远处的墙壁、大型装饰物。
-
最低(256/128): 高处的电线杆、地面掉落的小碎石、远景的楼房。
-
-
匹配原则: 如果一个物体在屏幕上看起来只有 10 像素宽,你给它 4K 贴图就是犯罪。你应该根据物体在游戏中的平均占据大小来决定其贴图分辨率。
-
黑盒思维:在材质函数、蓝图类中封装复杂逻辑,只暴露必要输入/输出
3.3 Lumen 全局光照(项目设置与性能影响)
项目设置:Lumen 详解
Lumen 是 UE5 的动态全局光照系统。在移动端,目前的建议是:全部关闭。 手机跑不动 Lumen。
-
项目设置:
-
软件光线追踪 (Software Ray Tracing): 使用网格体距离场(Mesh Distance Fields)。消耗中等,不支持复杂的几何体变形。
-
硬件光线追踪 (Hardware Ray Tracing): 需要 RTX 显卡。支持 Nanite 细节,精度极高,消耗巨大。
-
-
性能影响: Lumen 每帧都会在后台更新巨大的“场景缓存(Scene Cache)”。
-
移动端警告: Lumen 不支持移动端。 如果你在项目中开启了 Lumen,而又强行在移动预览模式下运行,引擎可能会因为无法回退到静态光照而产生巨大的性能冗余。
-
建议: 移动端请将全局光照设为 None 或 Screen Space,并靠 烘焙 Lightmaps 解决光影。
-
UE5.7中的lumen设置分别对应以下的作用:
-
硬件光线追踪: 利用显卡专门的 RT 核计算光线,效果最好但最吃资源。
-
光线光照模式: 决定光线如何反弹(表面缓存效率高,命中光照更精确)。
-
高质量半透明反射: 让玻璃等透明物体能反射出场景。
-
屏幕追踪源 (Screen Tracing): 利用屏幕上已有的像素做近似光影。
-
场景颜色: 影响全局光照的色彩反馈。
4. 引擎核心系统(UE5 特有)
-
蓝图逻辑:变量、函数、宏、事件;蓝图接口(BPI)
-
蓝图逻辑与变量的作用域和执行堆栈区别。
-
A. 变量 (Variables) 的高级控制
-
Instance Editable (小眼睛开启): 勾选后,变量会暴露在关卡编辑器中。这意味着你可以在不打开蓝图的情况下,为场景中不同的“路灯”设置不同的颜色。
-
Expose on Spawn: 非常实用。当你用
SpawnActorFromClass生成物体时,这个变量会直接出现在生成节点的输入端。 -
Enum (枚举): 这是一个“可读性”神器。不要用
Int记录状态(0=跑,1=跳),而要定义一个枚举。它是强类型的,能防止你传错数据,且在Switch节点下逻辑极其清晰。
B. 函数 (Functions) vs. 宏 (Macros) vs. 事件 (Events)
这是最容易混淆的地方:
| 特性 | 函数 (Function) | 宏 (Macro) | 事件 (Event) |
| 底层本质 | 真正的子程序调用,有自己的局部变量堆栈。 | 纯粹的“代码展开”,编译时把节点复制到调用处。 | 程序的入口点,通常用于响应外部信号。 |
| 局部变量 | 支持。 | 不支持。 | 不支持。 |
| 延迟逻辑 | 禁止。不能放 Delay 或 Timeline。 |
支持。可以放 Delay。 |
支持。支持所有异步操作。 |
| 返回值 | 可以有多个输出引脚(Return)。 | 像普通节点,可以有多个输出路径。 | 无返回值(除非通过参数传递引用)。 |
| 适用场景 | 复杂的数学计算、getter/setter 逻辑。 | 简单的流转封装、重复的连线组合。 | 碰撞检测、输入响应、RPC 网络通信。 |
C.蓝图接口 (BPI)
-
BPI: 沟通协议。
-
位置: 右键 -> Blueprints -> Blueprint Interface。
-
使用: 只要物体都带着这个“接口”,不管它是门还是宝箱,玩家发送“交互”信号,它们都能各自执行自己的逻辑,且不需要互相引用对方。
-
流式加载(Level Streaming)、异步处理、对象池
-
流式加载 (Level Streaming)
-
含义: 像看视频缓冲一样加载场景。
-
实现: 将世界切成 A、B、C 块。当玩家走进 A 触发器,自动加载 B;离开 A 后,卸载 A。UE5 的 World Partition 已经自动化了这个过程。
-
异步处理 (Asynchronous Processing)
-
意义: 让耗时任务(加载大贴图、算数学题)不卡死主线程(画面不掉帧)。
-
实现:
-
如何实现流式加载(具体操作步骤)
在 UE5 中,最推荐的是使用 World Partition(世界分区)。
-
开启世界分区:
Project Settings->World Partition-> 勾选Enable World Partition。 -
设置 Grid(网格): 在
World Partition Editor窗口中,你可以看到整个场景被切成了无数个小方块。 -
设置加载范围: 选中网格,设置
Loading Range(例如 50000 厘米)。 -
运行逻辑: 当玩家角色靠近某个网格,该网格内的模型、贴图会自动从硬盘加载到内存;当玩家远离,它们会自动卸载。
-
手动流送(Level Streaming): 如果你不用世界分区,可以通过
Load Stream Level节点,根据触发器(Trigger Box)来手动控制子关卡的加载。 -
Async Load Asset: 蓝图节点,在后台加载东西,加载完后给你个通知。
-
Timer (定时器): 设置逻辑在 5 秒后执行,而不是在 Tick 里每帧判断。
-
-
对象池 (Object Pooling)
-
逻辑: 子弹打出去后,不要销毁 (Destroy),而是隐藏并回收进一个仓库。
-
目的: 消除频繁创建物体导致的内存碎片和 CPU 高峰。
-
象池的核心是不进行真正的
Destroy(销毁)和Spawn(生成),而是进行 显隐状态切换 和 数据重置。 -
调用步骤:
-
初始化: 在游戏开始(BeginPlay)时,生成 50 个物体,将它们全部
Set Hidden in Game(true)并关闭Collision。 -
获取(Get): 当你需要子弹时,遍历数组找到第一个“非激活”状态的物体。
-
激活: 将该物体的坐标
SetWorldLocation移动到枪口,开启显示和碰撞。 -
回收(Return): 当物体碰到墙壁或存活时间到期,不要销毁,而是再次将其隐藏并移回一个“储藏区”(比如坐标 0,0,-99999)。
-
-
PSO 卡顿、间歇性延迟(Hitch)的定位与缓解
-
PSO (管线状态对象) 卡顿
-
痛点: 玩家第一次开火时突然卡一下。
-
原因: GPU 还没见过这个特效的 Shader,正在现算(编译)。
-
解决: PSO Caching。在发布前跑一遍游戏,收集所有 Shader 记录,打包进安装包。游戏启动时提前让 GPU 预热这些 Shader。
-
间歇性延迟 (Hitch)
指突然跳出的一帧耗时极长。
-
排查: 通常是 Garbage Collection (GC) 在大规模清理内存,或者是从硬盘读取大资产导致的 I/O 堵塞。
5. 性能分析与优化(TA 核心价值)
抗锯齿(MSAA vs TAA)与超分技术(FSR、TSR、DLSS),移动端 TBDR 下 MSAA 的收益
合批处理就是合并材质吗?
不完全是,但常常是。“合批”的直接目标是把一堆 Draw Calls 变成一个,共享同一个材质是实现它的核心前提。实际的合批过程是将符合条件的不同物体的顶点数据合并成一个大 Buffer 再提交给 GPU。
GPU 分析工具:RenderDoc、Unreal Insights、移动端 Profiler
当 stat RHI 给不出具体原因时,你需要这些专业工具:
-
抗锯齿(Anti-Aliasing)对比
技术 全称 特点 推荐平台 FXAA 快速近似 边缘模糊,极快。 低配手机 TAA 临时抗锯齿 效果好,但画面动起来会糊(鬼影)。 中配手机 / PC MSAA 多重采样 画面最清晰,但非常吃显存空间。 移动端首选 (配合 Forward Rendering) TSR 临时超分辨率 UE5 特有,类似 DLSS,高清画质。 高端 PC SMAA 亚像素形态学 比 FXAA 清晰,比 TAA 快。 中配 PC -
TBDR 下 MSAA 的收益
移动端 GPU(如 Adreno/Mali)大多采用 TBDR (分块延迟渲染) 架构。
-
原理: 手机显卡会将屏幕切成 16x16 的小块(Tiles),在显卡内部极速计算。
-
MSAA 收益: 在这种架构下,MSAA (多重采样抗锯齿) 的计算是在芯片内部完成的,几乎不占用显存带宽。
-
对比: TAA 需要采样历史帧,会导致手机发热严重且画面模糊;MSAA 则能提供非常锐利且低开销的边缘。
-
操作: 在移动端开启 Forward Shading (前向渲染),然后开启 MSAA 4x。
-
-
超分辨率技术:FSR, TSR, DLSS
这些技术的目标都是:低分辨率渲染,高分辨率输出。
-
FSR (AMD): 基于数学算法的拉伸。
-
TSR (UE5): 引擎内置的算法,效果比 FSR 更稳定。
-
DLSS (NVIDIA): 必须有 RTX 显卡。它利用 AI(深度学习)来“猜”丢失的像素,效果目前是行业最强。
-
它们算抗锯齿吗? 算。 它们在放大的同时,利用历史帧信息消除了锯齿,所以它们现在基本替代了传统的 TAA。
-
FSR (AMD FidelityFX Super Resolution): 跨平台的超分辨率技术。
-
开启: 需下载对应的插件。在
Project Settings中开启插件后,控制台输入r.FSR.Enabled 1。
-
-
TSR (Temporal Super-Resolution): UE5 官方自研的抗锯齿+超分辨率技术。
-
开启:
Project Settings->Rendering->Anti-Aliasing Method选为Temporal Super-Resolution (TSR)。 -
意义: 它们都允许你以 1080P 的分辨率渲染画面,却输出接近 4K 的清晰度。
-
-
移动端性能策略:内存预分配、带宽优化、发热控制
-
移动端内存预分配
-
方法: 在
Project Settings -> Streaming下,手动设置Pool Size(纹理池大小)。 -
目的: 启动游戏时就给贴图划好 512MB 的地盘。这样不会在游戏进行中因为不断申请内存而造成微卡顿。
纹理池 (Texture Pool) :
它是一块预留给系统管理的专用显存区域,用于存放游戏运行时会用到的所有纹理。它存在的核心目的,就是为了避免显存被瞬间占满导致游戏卡顿,并在不同纹理间进行高效切换。
-
移动端性能策略:带宽与发热
手机端最怕的不是计算量,而是 带宽 (Bandwidth),即数据在内存和显卡之间搬运的速度。
-
内存预分配: 设置
r.Streaming.PoolSize。给贴图划定地盘,防止系统频繁申请内存。 -
带宽优化:
-
减少采样器: 材质中贴图数量越少越好(使用通道打包)。
-
纹理压缩: 必须使用 ASTC 格式。
-
-
发热控制:
-
限制帧率: 手机端跑 30 帧比不稳定的 60 帧要好得多。
-
指令减法: 材质指令超过 150 条时,手机外壳就开始烫手了。
-
-
Draw Call 优化、合批、LOD 与剔除(视锥体、遮挡)
-
Draw Call 是 CPU 告诉 GPU 画东西的次数。
-
Draw Call优化
-
Draw Call 优化是图形性能优化的核心任务之一。目标很明确:减少 CPU 为提交渲染命令所耗费的时间,让 GPU 尽可能满载。
下面是经过实践验证的几类主要优化方法,按效果从高到低排列:
1️⃣ 减少物体数量(最直接)
方法 原理 示例 视锥剔除 不提交相机视野外的物体 UE/Unity 自动做,但需合理设置包围盒 遮挡剔除 不提交被其他物体完全挡住的对象 预计算可见性(如 UE 的 Precomputed Visibility 或 Potentially Visible Sets) 距离剔除 超出设定距离的物体直接不渲染 远处的小物件、粒子 LOD 远距离使用低面数模型,虽不减少 DC,但降低顶点/像素负载,间接允许更高 DC 预算 重要 包围盒 (Bounding Box) :
是包裹 3D 模型的最小六面体,引擎用它来执行视锥剔除 (Frustum Culling) 和碰撞检测。UE 中默认使用 轴对齐包围盒 (AABB)。你可以在静态网格体编辑器 (Static Mesh Editor) 里为模型添加自定义的简单碰撞盒(如胶囊、盒体等),它也是导航网格生成的基本单位。
核心:不画看不见的东西。
2️⃣ 合并 Draw Call
🔹 静态批处理(Static Batching)
-
原理:将不移动、不改变材质的多个物体,在构建时合并为一个大网格(须共享同一材质)。
-
限制:会增加内存(副本网格),每个物体仍独立剔除。
-
最佳场景:建筑、石头、树木等大量静态场景物体。
-
🔹 动态批处理(Dynamic Batching)
-
原理:运行时自动将满足条件(小顶点数、相同材质)的小物体合并到一个 DC。
-
代价:每帧做合并计算,有 CPU 开销。适用于移动端小物体。
-
常见:Unity 内置,UE 无等价物(UE 用实例化替代)。
-
🔹 手动合并网格
-
原理:在 DCC 软件中将多个物体合并成一个网格,共享一套 UV/材质。
-
缺点:无法单独控制每个物体的剔除/变换,内存增大。
-
UE 动态批处理中的“实例化”和“静态批处理”有什么区别?
它们的目标都是减少 Draw Call,但路子完全不同。
-
静态批处理 (Static Batching):在编辑时就合并不同物体的网格。优点是合批效率最高,但不支持运行时移动。
-
实例化 (Instancing):在运行时使用一个网格和材质,通过传递不同参数(如位置、颜色)一次性绘制多个物体。支持动态,但不适用于骨骼网格体模型。
-
3️⃣ GPU 实例化(Instancing)
方法 说明 支持情况 传统实例化 一次 DC 绘制多个相同网格、相同材质的物体,仅传递不同变换矩阵 DirectX 11+ / Vulkan / Metal GPU Instancing 自动合并大量相同物体的渲染 Unity 的 Graphics.DrawMeshInstanced、UE 的 Instanced Static Meshes间接实例化 由 GPU 自己决定绘制多少实例(例如视锥剔除写在 Compute Shader 中) 高级用法,HPC 渲染 注:材质必须一致(允许贴图数组或 Per-instance 数据)。
-
4️⃣ 减少材质 / 着色器切换
-
排序渲染队列:将所有物体按材质 ID 排序 → 相同材质的连续画完。
-
使用材质实例:但注意实例不切换 Shader,切换材质参数开销极低;切换 Shader 或材质资源本身才是重量级操作。
-
合并纹理图集:将多个小贴图合成一张大图,使不同物体可共用同一材质(相同材质参数)。
-
排序渲染队列怎么能体现出优化?
-
对不透明物体,它减少了 GPU“画了又被盖住”的透支开销。
-
对于半透明物体,不排序会导致严重的视觉错误,比如透过窗户能直接看到墙壁背面的场景。
-
排序也能减少 GPU 状态切换,比如把使用相同材质 Shader 的物体排在一起渲染。
-
5️⃣ 利用 Advance 渲染技术
技术 降低 DC 的方式 GPU Driven Rendering CPU 只提交一个或几个 DC,GPU 自己做剔除、间接绘制(如 Mesh Shader 或 ExecuteIndirect) Nanite(UE5) 虚拟几何体系统,几何体粒度极细,但内部自动合并渲染,对用户透明 Batch 批 DX12 / Vulkan 下多 DC 可以打包进一个 Command List,减少 CPU 调用次数(但不是合并几何体) -
⚙️ 合批、LOD 与剔除三者的协作顺序(典型帧内)
-
视锥剔除(CPU)→ 剔除完全看不见的物体。
-
遮挡剔除(CPU + 可选 GPU 查询)→ 剔除被挡住的部分物体。
-
LOD 选择(CPU)→ 对剩下的物体,根据距离选择对应的网格。
-
合批(CPU)→ 将使用相同材质、符合合批条件的物体整理成更大的批次。
-
渲染(GPU)→ 提交批次,执行顶点/像素着色器。
-
注意:如果采用了 GPU Driven 渲染(如 Nanite),剔除和 LOD 全部移到 GPU 端,CPU 只负责很少的 Draw Call。
-
技术 目标 执行位置 减少什么 典型代价 视锥剔除 去掉镜头外的物体 CPU 不需要的 Draw Call 低 遮挡剔除 去掉被挡住的物体 CPU/GPU 不必要的渲染 (overdraw) 中(预计算)或高(实时) LOD 远处物体简化 CPU 顶点/像素处理量 低(内存换性能) 合批 减少 Draw Call CPU CPU 渲染线程耗时 内存、合并开销 最佳实践:优先保证剔除正确,其次使用 LOD 控制负载,最后用合批压榨 CPU 提交效率。
-
🧠 记忆口诀
看不到的不画(剔除),相同的合并(批处理),同类的一次画(实例化),材质别老换(排序),能用 GPU 让 GPU 干。
-
Unreal Insights: 它能录制 CPU 每一微秒在干什么。如果是因为某个蓝图 Tick 太重,或者某个渲染指令堵塞,它会显示一条长长的红色色块。
-
RenderDoc: 它可以“冻结”一帧,让你看 GPU 画这一帧的每一个步骤(Step-by-step)。你可以看到是哪一个 Draw Call 耗时最长。
-
移动端 Profiler: 苹果用 Xcode Instruments,高通安卓用 Snapdragon Profiler。它们能直接读到手机芯片的实时负载。
6. 工程与规范
-
SVN / Git 版本控制,资产锁定与提交规范
-
SVN (Subversion):
一种版本控制系统(类似 Git)。由于游戏项目的文件(模型、贴图)非常大,Git 处理起来很吃力,所以游戏行业大量使用 SVN 来管理美术资产。它能记录谁改了哪个贴图,并允许你回退版本。
-
游戏内的“黑盒”:
通常指功能封装。在 UE 中,通过将复杂的逻辑封装在
Material Function或Blueprint Class中,只暴露几个接口(Input/Output)。外部不需要知道内部怎么算的,只需要给输入值,这就是“黑盒”思维。 -
SVN 详细操作指南(资产版本管理)
SVN 对美术资产(.uasset)的支持远好于 Git。
-
Checkout (检出): 把服务器仓库的东西拉到本地电脑。
-
Lock (加锁): 最关键步骤! 改模型/贴图前必须点 Lock,防止别人也改它,因为 .uasset 文件无法合并冲突。
-
Update (更新): 每天开工第一件事。
-
Commit (提交): 改完了解锁并上传。
-
Revert (回退): 改乱了?直接一键回到服务器上的版本。
-
如何实现 SVN(详细设置流程)
SVN 的核心是 “服务器 + 客户端” 架构。
-
安装服务端(如 VisualSVN Server): 找一台不关机的电脑(或云服务器),安装并新建一个
Repository(仓库)。你会得到一个 URL 链接。 -
安装客户端(TortoiseSVN): 在你的工作电脑安装它(俗称“小乌龟”)。
-
检出项目(Checkout): 在你的硬盘空白处右键 ->
SVN Checkout-> 输入服务器的 URL。 -
UE 集成: 在 UE 编辑器下方的
Source Control->Connect to Source Control-> 选择Subversion-> 填写 URL、账号、密码。 -
操作: 以后在内容浏览器里改了东西,右键就有
Check Out(加锁)和Submit(上传)选项了。 - Git 是什么?
Git 是目前全球最流行的分布式版本管理系统。
-
对比 SVN: SVN 只有一个中央仓库;Git 每个人本地都有一个完整的仓库副本。
-
优势: 适合代码管理,分支合并非常强大。
-
劣势: 处理巨大的美术资产(如 1GB 的贴图)时非常笨重,容易导致仓库体积爆炸。
-
资产锁定与提交规范
在团队开发(SVN/Perforce)中,为了防止文件冲突:
-
Check Out (锁定): 修改
.uasset前必须先锁定。UE 中图标会变成一个红色的勾,别人就没法改了。 -
原子提交: 相关的修改(比如你改了模型和对应的材质)要放在同一个提交记录(Changelist)里。
-
Submit (提交): 提交后系统会自动解锁,别人才能同步你的修改。
-
资产存储位置对照表,命名规范与配置层级
-
资产存储位置对照表
资产类型 存储位置 硬件处理核心 UV 坐标 存在模型(Mesh)的顶点数据中 GPU (Vertex Shader) 负责读取 贴图 (Texture) 存在显存 (VRAM) 中 GPU (Pixel Shader) 负责采样 游戏逻辑 存在内存 (RAM) 中 CPU 负责计算 RHI 指令 内存缓存区 CPU 生成,发往 GPU 执行
命名规范与配置层级
-
命名规范:
-
贴图:
T_BaseColor_D(D 代表 Diffuse/Data)。 -
材质:
M_Master(母材质),MI_Snow(材质实例)。 -
蓝图:
BP_WeatherSystem。
-
-
配置层级 (Config Hierarchy): UE 的设置读取顺序是:
Engine->Project->Platform(如 Android) ->User。-
实战: 如果你想针对手机降画质,不要改
DefaultEngine.ini,而要改Android/AndroidEngine.ini。
-
实践层
-
Shader 与材质的硬指标:
-
材质复杂度视图:必须能用引擎自带的“Shader Complexity”视图,一眼看出哪个材质是“性能杀手”(例如:绿色好,红色坏,白色直接爆了)。
-
具体指令数达标线:你需要知道,对于移动端,一个像素着色器的指令数最好控制在多少条以内(例如:基础物体 < 100 条,角色 < 200 条)。
-
这就是要把我之前汇总的节点知识,结合到这个框架的“3.2 材质逻辑与性能”里去学。
-
-
具体的工具操作流:
-
RenderDoc 截帧五步法:虽然框架里提了工具,但你需要知道具体的查看顺序(先看 Pass 数量,再看 Draw Call 密度,最后选一条 Draw Call 看输入输出)。
-
Unreal Insights 的 Trace:知道怎么开启、停止、导出,然后看哪几个关键线程(GameThread, RenderThread, RHIThread)的耗时。
-
-
针对流派的具体优化手册:
-
移动端特有坑:除了 TBDR,你还得知道 Alpha Test 对移动端杀伤力为何特别大(会禁用 Early-Z 或 HS R 优化),以及为什么非等宽纹理(NPOT)在部分老设备是地雷。
-
Lumen/Nanite 的“禁区”:知道什么情况下 Lumen 开销暴增(比如大面积植被),以及 Nanite 不支持的东西(动态模型、Masked 材质在移动端不做 Nanite 等)。
-
1. 节点与指令的对应关系:从图形到文本
在 UE 中,材质编辑器通过连线生成一份巨大的 Material.usf 文件。要理解代码,首先要建立“翻译”直觉。
如何查看 HLSL 代码
在材质编辑器菜单栏,点击 窗口 (Window) -> HLSL 代码 (HLSL Code)。你会看到一个极其冗长的文档,核心逻辑通常隐藏在以 CalcPixelMaterialParameters 或 GetMaterialPixelParameters 开头的函数中。
常用节点与代码映射表
| 材质节点 | HLSL 代码/表达 | 逻辑说明 |
| Add | a + b |
两个向量或数值相加 |
| Multiply | a * b |
逐元素相乘 |
| Lerp | lerp(a, b, s) |
线性插值:$a(1-s) + b(s)$ |
| Dot Product | dot(a, b) |
点积,常用于计算光照角度($\cos\theta$) |
| Texture Sample | Texture2DSample(Tex, TexSampler, UV) |
纹理采样函数 |
| Component Mask | value.rg 或 value.r |
获取向量的特定通道(Swizzling) |
建议: 试着连接一个最简单的
Add节点,然后在 HLSL 窗口里搜索+号,观察它是如何嵌套在函数体内的。
2. PBR 公式的 Shader 落地
PBR(基于物理的渲染)的核心目标是让材质在不同光照环境下表现一致。
BRDF 与 GGX
UE 主要使用 Cook-Torrance BRDF 模型。它将反射分为两个部分:漫反射(Diffuse) 和 镜面反射(Specular)。
-
GGX (Microfacet Distribution): 这是目前主流的法线分布函数。代码实现的核心是计算“微平面”有多大比例朝向相机。其公式在代码中体现为:
$$D(h) = \frac{\alpha^2}{\pi( (n \cdot h)^2 (\alpha^2 - 1) + 1 )^2}$$
其中 $\alpha$ 就是 Roughness 的平方。这就是为什么 Roughness 变化对高光形状影响如此之大的原因。
能量守恒(Energy Conservation)
在代码中,能量守恒遵循一个铁律:反射出去的光不能超过接收到的光。
-
实现方式:
Specular + Diffuse <= 1。 -
在 UE 代码中,当你增加 Metallic(金属度)时,代码会通过
lerp自动降低BaseColor对漫反射的贡献,将其转化为镜面反射的颜色。
Roughness/Metallic 如何驱动采样
-
Metallic: 决定了
BaseColor是作为漫反射(0)还是作为镜面反射颜色(1)。 -
Roughness: 决定了在采样环境贴图(CubeMap)时,使用哪一个层级的 Mipmap。越粗糙,采样越模糊(Mip 级别越高)。
3. 顶点着色器 (VS) 与 像素着色器 (PS) 的分工
理解这两者的分工是优化的基础。
顶点着色器 (Vertex Shader)
-
职责: 处理几何体信息(顶点位置、法线、切线)。
-
代码体现:
World Position Offset (WPO)。 -
优势: 计算频率低。一个 1 万面的模型只有约 5000 到 1 万个顶点。在此执行动画计算(如树叶摆动、时钟旋转)非常省资源。
像素着色器 (Pixel Shader)
-
职责: 处理每个像素的最终颜色。
-
代码体现: 几乎所有的纹理采样、光照计算。
-
劣势: 计算频率极高。在 1080p 屏幕下,每帧要运行约 200 万次计算。
性能准则: 如果一个计算逻辑(比如平移 UV 的
Time计算)可以在 VS 中完成,就不要放在 PS 里。UE 材质节点中的 Vertex Interpolator(顶点插值器)节点就是专门干这个的:在 VS 计算结果,然后传给 PS 直接使用。
4. 常用性能陷阱:避坑指南
Alpha Test (Masked) 与 Early-Z
-
陷阱: 在移动端或低性能平台,使用 Masked(遮罩)模式会破坏硬件的 Early-Z 优化。
-
原理: 显卡本可以在计算像素前就知道哪些物体被遮挡了,从而跳过计算。但如果使用了遮罩,显卡必须运行完 Shader 才知道这个像素是不是透明的,导致严重的性能浪费。
-
对策: 尽可能使用几何体剪裁,或者接受半透明(Translucent)的开销。
半透明排序与 Overdraw
-
Overdraw(过度绘制): 当多个透明层重叠时,同一个像素会被重复计算多次。
-
可视化检查: 在编辑器运行模式下,选择 优化视图模式 (Optimization Viewmodes) -> Overdraw。深红色或白色代表该处性能压力极大。
动态材质实例 (MID) 的参数更新
-
性能消耗: 在
Tick中使用SetScalarParameterValue是有开销的,因为它涉及到从 CPU 向 GPU 发送指令。 -
对策: 如果参数变化非常频繁(如每一帧都在变),考虑使用 Material Parameter Collection (MPC) 或者 Vertex Color 来传递数据,减少 API 调用次数。
-
网格体距离场是一个能快速判断“点到物体表面距离”的技术,主要用于高效的动态阴影和软环境光遮蔽(AO)。 -
Render Target是一个渲染的“幕后画板”,先在它上面绘制,再把结果用作纹理,是实现反射、动态特殊效果的基础。 -
Lightmap则是预先生成的静态“光照照片”,通过预计算将静态光照细节存入纹理,是兼顾高性能与高画质的基石。 -
Virtual Shadow Maps (VSM)是UE5主推的高性能虚拟化阴影技术,是为Nanite等精细化资产配套的高级动态阴影方案。
下面我们来看看它们的具体作用。
📏 网格体距离场 (Mesh Distance Field)
它的核心是一个有向距离场(Signed Distance Field,SDF)。简单来说,它会用一个体积纹理记录空间中的每一个点,到它最近的物体表面有多远:点在物体外部为正值,内部为负值。
这个技术的主要作用包括:
-
产生软阴影(Distance Field Shadows):比传统级联阴影贴图(CSM)更省性能,擅长为远处的物体投射柔和、自然的半影区域。
-
制作动态环境光遮蔽(Distance Field Ambient Occlusion):实现动态、柔和的全局遮蔽效果,让场景的立体感大幅提升。
-
GPU粒子碰撞:让粒子能高效地识别并与场景中的静态物体产生互动。
-
材质特效:你甚至可以在材质编辑器里引用它,制作出动态的流动贴图等有趣效果。
在使用方法上,你可以在项目的渲染(Rendering) > 软件光线追踪(Software Ray Tracing)菜单下,通过勾选 生成网格体距离场 来为整个项目全局开启,这会增加一些构建时间和内存开销。开启后,在定向光源的距离场阴影分类下勾选启用,并通过距离场阴影距离等参数调节作用范围和质量。
🖼️ 渲染目标(Render Target)
Render Target可以理解为GPU内部的一块“离屏”画板。常规渲染流程会直接绘制到屏幕,但有了渲染目标,我们可以先在幕后画板上创作,绘制好的画面能被当作纹理在后续流程中使用,为各种高级特效提供了基础。这种先离屏绘制再作为纹理使用的思路,是实现许多画面效果的关键。
你可以这样使用它:
-
创建:就像买一块新画板,需要在代码中创建一个指定宽高的
RenderTarget对象。 -
绘制:通知GPU“接下来请画在这块新画板上”,引擎会开始将几何体渲染到这个目标的内部中。
-
应用:绘制完成后,就到了一展身手的时候。生成的图像可以被当作普通纹理用在材质里,或者再次采样进行后处理。
-
复原:记得最后要把绘制目标重置回原始的“屏幕”(即Back Buffer),否则后面的画面就不知道画到哪儿去了。
利用这个工作流,你可以实现很多酷炫的效果:
-
实时镜子/监视器:创建一个渲染目标,内容来自镜子位置的相机,然后像贴图一样贴在模型上。
-
后处理特效:将整个场景先画到一个渲染目标上,再用一个全屏着色器对它进行处理,便能得到模糊、泛光等滤镜效果。
-
动态贴花:为了绘制一个弹孔,可以先把它渲染到一个独立的纹理,再投射到场景中。
-
小地图:用一个俯视相机将地图渲染到渲染目标上,就能生成实时更新的2D小地图。
💡 光照贴图(Lightmap)
Lightmap的核心思想叫光照烘焙(Light Baking),也就是预先计算场景中静态物体的光照信息,并将结果保存到一张或多张纹理中。运行时,材质直接采样这张图来获取明暗信息,就像一个物体自带了光照贴纸。它能以很低的开销输出高质量的静态光照效果。
它的渲染过程如下:
-
准备标记:在编辑器中将所有不动的物体和光源标记为“静态 (Static)”,表示它们参与光照烘焙。
-
分配坐标:引擎准备好模型专用的第二套UV通道(Lightmap UVs),用于在光照贴图上正确展开渲染结果。
-
执行烘焙:按下“烘焙 (Bake)”按钮,引擎(如Unity的Progressive Lightmapper)开始全局光照计算。
-
最终应用:烘焙完成,引擎自动将光照贴图与模型关联。运行时,Shader会把这张纹理和主纹理混合,展现出最终光影效果。
简单来说就是:准备标记 -> 分配坐标 -> 执行烘焙 -> 最终应用。
预计算可见性 (Precomputed Visibility):
本质是解决“哪些地方能看到哪些东西”的问题提前算好,运行时直接查表。主要适用于移动平台或有大面积遮挡物的场景。
操作步骤:在 World Settings > Precomputed Visibility 勾选启用,然后在关卡中放置 Precomputed Visibility Volume 调整其覆盖范围。最后重新构建光照 (Build Lighting),数据便生成完毕并进行剔除。
🎭 虚拟阴影贴图(Virtual Shadow Maps,VSM)
VSM是UE5推出的一项革命性的高精度阴影贴图技术。它的核心是虚拟化:维护一张16k x 16k像素的超大虚拟阴影贴图,再将它划分为许多128x128的小块(页),按需动态加载,实时渲染画面中的高精度阴影。
它的主要作用包括:
-
惊人的视觉精度:能完美配合Nanite的超高精度几何体,不再需要在阴影质量和性能间做痛苦的权衡。
-
全局统一的柔和阴影:为整个场景提供统一、物理正确的柔和阴影边缘(半影区),大大提升了真实感。
-
简化的工作流程:旨在提供一种“开箱即用”的设置,自动适应项目需求,几乎不需要手动调整复杂的参数。
在使用方法上,你可以在项目设置的引擎(Engine) > 渲染(Rendering)中,将阴影贴图方法设置为 虚拟阴影贴图 (新项目默认开启),启用后它将替换掉CSM等传统阴影方案。
额外
-
后处理效果:掌握 SceneTexture 节点的用途,写一个基于深度的雾效。
-
自定义节点:在材质中使用 Custom 节点插入 HLSL 代码,实现节点做不到的循环或数学操作。
-
移动端专用 Shader:理解 TBDR 下尽量减少 Render Target 切换,利用
min16float等低精度。 -
Compute Shader(高级):用 Niagara 或 RenderGraph 驱动 GPU 粒子或流体,这是加分项。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)