渲染

本页面为自动翻译,可能包含错误。如果发现问题,请通过“编辑此页面”链接帮助修正。

Turian 使用单一的 SDL3-GPU 渲染器(Vulkan / Metal / D3D12)进行 3D 渲染, 该渲染器由编辑器视口发布游戏共享——因此你在编辑时看到的就是游戏实际绘制的内容: 金属粗糙度 PBR、方向阴影映射、法线映射,以及压缩纹理(BCn / KTX2)的直接支持。

两个小型模块

渲染器被拆分为与引擎无关的包,这样它就不会与编辑器的 UI 工具包耦合:

  • gpu —— 基于 SDL3 GPU API 的轻量窗口 + GPU 设备平台层。它拥有操作系统窗口、设备和交换链,并暴露转换后的 SDL3 API 以及每帧命令缓冲区。它还提供了一个截图辅助函数(纹理回读 → TGA),便于调试。
  • render —— 场景渲染器:PBR 管线、阴影通道、网格/纹理上传和绘制循环。它依赖于 gpu 和引擎的场景/资源类型,并通过回调函数接收 GPU 设备、颜色目标、场景节点和资源字节数据——不依赖 UI。

编辑器向 render 提供 dvui 的设备和一个离屏目标;游戏提供 SDL 窗口的交换链。两者都通过 GUID 从相同的字节源接口解析资源(网格、纹理、材质)——在编辑器中从预处理的 .cache 中读取,在游戏中从打包的 .oap 中读取。

软件回退

当 SDL3 GPU 不可用时(例如无头 CI),游戏会回退到 CPU 软件光栅化器。正常构建默认使用 GPU 路径。

光照

每帧最多支持 8 个光源(方向光 / 点光源 / 聚光灯)。第一个投射阴影的方向光驱动级联阴影贴图(4 个分区,每个分区在阴影图集中有自己的 PCF 滤波条带),因此阴影细节在相机附近保持清晰,同时不会牺牲大场景的覆盖范围。金属材质会拾取环境镜面反射项,因此在没有环境探针的情况下不会呈现黑色。有关 LightMeshRenderer 组件,请参阅组件;有关 PBR 材质模型,请参阅资源与材质

基于图像的照明

Environment 组件(每场最多一个活动)指向一个等距柱状 HDR 贴图,同时驱动天空盒背景和环境光照:

  • 天空盒——等距柱状纹理直接按视线方向采样;关闭 show_skybox 可以保留环境贡献,同时回退到渲染器的纯清空颜色,在没有繁忙的 HDRI 争夺注意力的情况下迭代几何体/材质时很有用。
  • 漫反射辐照度——每次环境贴图上传时投影到二阶球谐基中(逐像素计算成本低,且对于纯漫反射项已经正确——无需完整的漫反射立方体贴图卷积)。
  • 镜面反射——GGX 重要性采样的预过滤立方体贴图:上传时,等距柱状贴图转换为基础立方体贴图,然后每个 mip 级别以递增的粗糙度进行预过滤(标准拆分求和法),在着色时按反射方向和粗糙度选择的 mip 级别进行采样。这取代了早期在 UV 空间进行盒式滤波的等距柱状 mip 近似——它在极点附近过度模糊,并且在掠射角没有真正的 GGX 波瓣形状。环境 BRDF 项使用 Karis 的解析近似,而不是预烘焙的 2D LUT。

所有这些都在每次环境纹理上传时发生一次,而不是每帧——除了初始立方体贴图生成外,没有运行时成本。

色彩管理

光照在线性空间中运行:颜色纹理(漫反射、自发光)以 sRGB 采样——对于带标签的 DDS/KTX2 纹理,由 GPU 采样器解码为线性;或通过导入器烘焙到 PNG/JPEG 源中的小程序——而数据贴图(法线、金属粗糙度、环境光遮蔽)始终保持线性。主通道渲染到 HDR(R16G16B16A16_FLOAT)目标,而不是直接写入色调映射后的颜色;后处理合成通道在最后应用 ACES 电影色调映射和 gamma-2.2 编码,此时渲染目标和交换链为 UNORM(非 sRGB)。软件光栅化器在其着色函数中直接镜像这两个步骤,以保持 GPU 和 CPU 路径之间的一致性(它没有单独的后处理阶段)。

后处理

一个仅限 GPU 的后处理堆栈在光照通道之后、色调映射之前/与之结合运行:暗角、逐通道 RGB 提升/伽马/增益颜色分级和泛光。设置位于 PostProcessVolume 组件上,而非相机上——将其添加到任何场景对象,它要么是全局的(影响整个场景),要么是局部的(该对象周围的盒子/球体区域,边缘有 blend_distance 衰减)。每个效果类别都有自己的启用开关:

  • 暗角——intensity(0 = 关闭)、radiussmoothness 控制从中心向外的径向暗化。
  • 颜色分级——liftgammagain(每个都是 RGB 三元组)应用与 Unity 调色轮相同的 Lift/Gamma/Gain 模型:lift 调整阴影,gamma 调整中间调,gain 调整高光,每个通道独立运作,因此您可以调整色彩平衡(例如,暖色阴影、冷色高光)而不仅仅是亮度。
  • 泛光——threshold(像素发光的线性 HDR 亮度)、intensity(0 = 关闭)和 radius(发光扩散)驱动多 mip 双滤波器泛光,因此自发光或镜面过曝的表面会发出柔和、宽阔的光晕,而不是小的固定半径模糊。

禁用所有类别的 PostProcessVolume 是硬性空操作——完全没有体积的场景渲染结果与没有后处理时完全一致。

重叠体积

多个体积可以同时影响相机——例如,整个关卡的全局"外观"加上特定房间或时刻的局部体积。重叠通过优先级(越高越优先)和基于距离的权重(局部体积形状内部为 1,在其 blend_distance 上渐变为 0)解决,按类别混合,因此一个体积可以仅覆盖暗角,而分级和泛光仍然来自其他活动的体积。混合每帧根据相机的实际位置进行评估,因此在编辑器中飞过体积边界会预览与发布游戏相同的淡入淡出效果。

自定义效果

引擎/插件代码可以通过 subsystems/render/postprocess.zig 中的 postprocess.registerEffect 注册额外的后处理通道——直接读写 HDR 缓冲区,因此它可以执行自己的高亮提取或 HDR 空间分级工作。注册的效果按注册顺序运行,在内置泛光生成之后、最终合成之前;这是一个 Zig 级别的扩展点(启动时注册一次),而不是实时/编辑器创作的着色器系统。

由于泛光需要未缩放的 HDR 亮度数据,后处理需要上述 HDR 主通道——它在软件渲染器中不可用。


← 所有文档 编辑此页面