Deferred Shading Pipeline延迟渲染管线
GBuffer LayoutGBuffer 布局
NeoX's deferred path uses a compact 3-RT GBuffer for the standard mode, or a 5-RT Single-Pass Deferred for mobile (TBDR) optimization. In the new engine the GBuffer layout changed: Roughness moved from RT1 to RT2, and the RT names were updated. A new shared gbuffer_struct.hlsl header is now used across all GBuffer passes.
NeoX 的延迟路径标准模式使用紧凑的 3-RT GBuffer,或为移动端(TBDR)优化使用 5-RT 单 Pass 延迟。新引擎 GBuffer 布局有变化:Roughness 从 RT1 移到 RT2,RT 名称也已更新。新引擎所有 GBuffer Pass 现在使用共享的 gbuffer_struct.hlsl 头文件。
deferred_shading_gbuffer.hlsl changes the GBuffer packing: Roughness moved from NormalRoughness.w (RT1 Alpha) to MetallicRoughnessShadingModelFlags.g (RT2 Green). Flags moved from .g (RT2 Green) to .a (RT2 Alpha). RT1 renamed from NormalRoughness to Normal. RT2 renamed from MetallicShadingModelFlags to MetallicRoughnessShadingModelFlags. The old res/shader/ version is no longer used at runtime since the new file takes priority.
新版替换(GBuffer 布局变更):新 deferred_shading_gbuffer.hlsl 改变了 GBuffer 打包方式:Roughness 从 NormalRoughness.w(RT1 Alpha)移到 MetallicRoughnessShadingModelFlags.g(RT2 Green)。Flags 从 .g(RT2 Green)移到 .a(RT2 Alpha)。RT1 从 NormalRoughness 改名为 Normal。RT2 从 MetallicShadingModelFlags 改名为 MetallicRoughnessShadingModelFlags。旧版在运行时不再使用,新文件优先。
GBuffer Write — ps_main()GBuffer 写入 — ps_main()
The GBuffer pixel shader now includes gbuffer_struct.hlsl (a shared struct definition), and the packed layout changed — Roughness is in RT2.g and Flags are in RT2.a:
GBuffer 像素着色器现在包含 gbuffer_struct.hlsl(共享结构体定义),打包布局变化——Roughness 在 RT2.g,Flags 在 RT2.a:
// From gbuffer_struct.hlsl (new shared header) struct GBuffer { float4 AlbedoAO : SV_Target0; float4 Normal : SV_Target1; // was NormalRoughness float4 MetallicRoughnessShadingModelFlags : SV_Target2; // was MetallicShadingModelFlags }; GBuffer ps_main(Fragment input, bool is_front_face : SV_IsFrontFace) { #if ENABLE_VIRTUALTEXTURE_SAMPLEING SamplingVirtualTexture(input); // NEW: VT sampling before material #endif RawData raw_data = GetRawData(input); Material mtl = (Material)0; SetupMaterial(input, raw_data, mtl); #if DEFERRED_DECAL_ENABLE && !ENABLE_VIRTUALTEXTURE_SAMPLEING DeferredApplyNewDecal(input, mtl); // conditional guard added #endif GBuffer gbuffer; gbuffer.AlbedoAO = float4(mtl.albedo, mtl.occlusion); gbuffer.Normal = float4(0.5 * (mtl.normal + 1.0), 0); // A channel now free // Encode flags into alpha byte (was green byte in old engine) uint flags = 0; flags = EncodeShadingModel(flags, mtl.shading_model); flags = EncodeReceiveShadow(flags); #if SLPV_ENABLE && LIGHT_PROBE_ENABLE // changed condition flags = EncodeClusteredShadingLightProbeVolumeEnable(flags); #endif gbuffer.MetallicRoughnessShadingModelFlags = float4( mtl.metalness, mtl.roughness, // NEW: Roughness in .g (was in RT1.a) 0, float(flags) / 255.0 // Flags in .a (was in .g) ); return gbuffer; }
Single-Pass Deferred — Mobile Optimization单 Pass 延迟 — 移动端优化
On tile-based deferred rendering (TBDR) GPUs (iOS/Android), NeoX supports Single-Pass Deferred Shading. This writes both GBuffer data AND lighting result in one pass, avoiding the costly off-chip GBuffer readback that destroys TBDR benefits.
在基于 Tile 的延迟渲染(TBDR)GPU 上(iOS/Android),NeoX 支持单 Pass 延迟着色。在一个 Pass 中同时写入 GBuffer 数据和光照结果,避免了破坏 TBDR 优势的昂贵离片 GBuffer 回读。
// Single-pass mode: output emissive directly + manual depth #if SINGLE_PASS_DEFERRED_SHADING_ENABLE gbuffer.FinalResult = float4(mtl.emissive, 1); #ifdef NEOX_GLSL gbuffer.Depth = input.position.z; // single float #else gbuffer.Depth = float4(input.position.z); // packed #endif #endif
Flag Encoding System标志位编码系统
The Alpha channel of MetallicRoughnessShadingModelFlags packs multiple boolean flags into a single byte (0-255). In the new engine the flags moved from the Green to the Alpha channel. Defined in flags.hlsl:
MetallicRoughnessShadingModelFlags 的 Alpha 通道将多个布尔标志打包到单个字节(0-255)中。新引擎中标志从 Green 通道移到 Alpha 通道。定义在 flags.hlsl:
| Flag标志 | Bits位 | Purpose用途 |
|---|---|---|
| ShadingModel | bit 0-3 | Which shading model (0=Isotropy, 1=Skin, 2=Hair...12=Water, 13=Cloth, 14=Glint, 15=Sheen)哪个着色模型(0-11 同旧版,12=Water, 13=Cloth, 14=Glint, 15=Sheen) |
| ReceiveShadow | bit 4 | Whether this pixel receives dynamic shadows此像素是否接收动态阴影 |
| LightProbeVolume | bit 5 | SLPV light probe active (condition changed: SLPV_ENABLE && LIGHT_PROBE_ENABLE)SLPV 光照探针激活(条件变更) |
| BakedShadow | bit 6 | Use baked shadow from light probe使用来自光照探针的烘焙阴影 |
CLUSTERED_SHADING_LIGHT_PROBE_VOLUME_ENABLE || LIGHT_PROBE_ENABLE to the more concise SLPV_ENABLE && LIGHT_PROBE_ENABLE. The new GBuffer includes DEFERRED_DECAL_ENABLE and ENABLE_VIRTUALTEXTURE_SAMPLEING guards that did not exist in the old version.
新版替换:Flags 从 Green 通道移到 Alpha 通道。光探针条件从 CLUSTERED_SHADING_LIGHT_PROBE_VOLUME_ENABLE || LIGHT_PROBE_ENABLE 改为更简洁的 SLPV_ENABLE && LIGHT_PROBE_ENABLE。新 GBuffer 包含旧版中不存在的 DEFERRED_DECAL_ENABLE 和 ENABLE_VIRTUALTEXTURE_SAMPLEING 保护。
NeoX vs UE5 GBuffer ComparisonNeoX vs UE5 GBuffer 对比
| Aspect方面 | NeoX (New Engine) | UE5.6 |
|---|---|---|
| RT CountRT 数量 | 3 (standard) / 5 (single-pass)3(标准)/ 5(单 Pass) | 5-6 (SceneColor + GBuffer A/B/C/D + Velocity)5-6 个 |
| Normal Encoding法线编码 | 0.5*(normal+1) in RT1 (RGB8/16) | Octahedron encoding (2-channel)八面体编码(2 通道) |
| Roughness slotRoughness 槽位 | RT2.g (new) — freed RT1.a for other useRT2.g(新)——RT1.a 释放可供他用 | GBufferB.a or GBufferC.g |
| Shading Model ID着色模型 ID | 4-bit field in Flags alpha byte (RT2.a)Flags alpha 字节中的 4 位(RT2.a) | 4-bit in GBufferB.aGBufferB.a 中 4 位 |
| Custom Data自定义数据 | None (limited by 3 RTs)无(受 3 RT 限制) | GBufferD (full RGBA for SSS color, cloth, etc.)GBufferD(完整 RGBA 用于 SSS 颜色等) |
| Shared struct共享结构体 | gbuffer_struct.hlsl (new)(新) | Various headers各头文件 |
| Bandwidth带宽 | Lower (3 RT = less memory traffic)更低(3 RT = 更少内存流量) | Higher (5+ RT = more flexibility)更高(5+ RT = 更多灵活性) |