Pipeline Overview管线概览

NeoX's primary rendering path is forward shading — every visible pixel evaluates its material and all affecting lights in a single pass. This is configured by forward_shading.render (the pipeline declaration XML). The new engine's shader grew from 285 to 502 lines with major new feature additions.

NeoX 的主要渲染路径是前向着色——每个可见像素在单次 Pass 中计算其材质和所有影响光源。这由 forward_shading.render(管线声明 XML)配置。新引擎着色器从 285 行增长到 502 行,新增了大量特性。

+=====================================================================+ | NeoX Forward Shading -- Single Pass Flow (New Engine) | +=====================================================================+ | | | vs_main(Vertex input, uint vertex_id, uint instanceID) | | +-------------------------------------------------------------+ | | | 00 ApplyUE4Scale() // import-from-UE4 compat | | | | 01 TransformCommonVertex() // model->world | | | | OR TransformCommonVertexImposter() (FOLIAGEIMPOSTER) | | | | 02 ApplyVertexOffsetLocal() // vertex animation | | | | 03 SetupFragmentAfterLocalOffset() | | | | 04 DoSkin() / DoSkin8() // 4 or 8-bone GPU skinning| | | | 05 Transform(world_mat) // world position | | | | 06 ApplyCustomizedUV() // NEW: custom UV | | | | 07 ApplyVertexOffsetWorld() // WPO world space | | | | 08 SetupFragment() // pack interpolants | | | | 09 ENABLE_REFLECTION_PROBE_INSTANCING / USE_GAEA_COLOR_PICK | | | | 10 DepthBias / Skybox / Bake / IS_PARABOLOID | | | +-------------------------------------------------------------+ | | v rasterize | | ps_main() | | +-------------------------------------------------------------+ | | | 11 ENABLE_VIRTUALTEXTURE_SAMPLEING: SamplingVirtualTexture| | | | 12 GetRawData() // sample all textures | | | | 13 SetupMaterial() // fill Material struct | | | | 14 PARTICLE_SYSTEM_GPU: clip dead particles | | | | 15 CalcLightingData() // precompute NdotV etc. | | | | 16 for each Light: | | | | +-- Shadow sampling (Render 3.0 CSM / paraboloid) | | | | +-- DirectLighting() -> diffuse + specular | | | | +-- accumulate | | | | 17 EnvLighting() // SH + IBL + bent normal | | | | 18 Apply fog, emissive, AO | | | | 19 USE_PIXEL_DEPTH_OFFSET: ApplyPixelDepthOffset() | | | | 20 LDR correction (ALPHA_TO_COVERAGE / SSS curvature) | | | | 21 Tone mapping (ACES) | | | | 22 NaN guard: -min(-pixel.Color, 0.0) | | | | 23 Output: SV_Target0 [+ optional VT write / HLOD bake] | | | +-------------------------------------------------------------+ | +=====================================================================+

Vertex Shader Stage顶点着色器阶段

The vertex shader performs geometry transformation with support for GPU skinning (up to 90 bones with 4 weights, or 8 weights with GPU_SKIN_8_ENABLE), vertex animation, foliage imposter rendering, and special projection modes. Two new parameters were added: SV_VertexID and SV_InstanceID:

顶点着色器执行几何变换,支持 GPU 蒙皮(4 权重最多 90 根骨骼,或通过 GPU_SKIN_8_ENABLE 支持 8 权重)、顶点动画、植被 Imposter 渲染和特殊投影模式。新增了两个参数 SV_VertexIDSV_InstanceID

01Transform Chain (New Engine)变换链(新引擎)

Fragment vs_main(Vertex input,
                  uint vertex_id   : SV_VertexID,    // NEW
                  uint instanceID  : SV_InstanceID) { // NEW
  #if IMPORT_FROM_UE4
    ApplyUE4Scale();  // scale compensation for UE4-exported assets
  #endif
  #if FOLIAGEIMPOSTER_ENABLED
    CommonVertex vert = TransformCommonVertexImposter(input, vertex_id, vert_inter);
  #else
    CommonVertex vert = TransformCommonVertex(input, vert_inter);
  #endif
  ApplyVertexOffsetLocal(vert, vert.position);
  SetupFragmentAfterLocalOffset(...);     // NEW intermediate setup step

  #if GPU_SKIN_ENABLE
    DoSkin(vert.blendWeights, vert.blendIndices, ...);
  #elif GPU_SKIN_8_ENABLE
    DoSkin(..., texcoord5, texcoord6, ...);  // NEW 8-bone skinning
  #endif

  float4 world_position = Transform(vert.world_mat, vert.position);
  ApplyCustomizedUV(frag, vert);           // NEW custom UV transform
  ApplyVertexOffsetWorld(...);
  SetupFragment(...);
}
New vs replaced (res_upgrade → res fallback): The new engine's forward_shading.hlsl in res_upgrade/ replaces the old 285-line version. New features added by the replacement: SV_VertexID/SV_InstanceID parameters, FOLIAGEIMPOSTER_ENABLED, GPU_SKIN_8_ENABLE, IMPORT_FROM_UE4, ApplyCustomizedUV, and SetupFragmentAfterLocalOffset. The old version (4-weight skinning only, no vertex ID) is no longer used at runtime since the new file takes priority. 新版替换(res_upgrade → res 回退):新引擎 res_upgrade/ 中的 forward_shading.hlsl 替换了旧版 285 行版本。替换新增功能:SV_VertexID/SV_InstanceID 参数、FOLIAGEIMPOSTER_ENABLEDGPU_SKIN_8_ENABLEIMPORT_FROM_UE4ApplyCustomizedUVSetupFragmentAfterLocalOffset。旧版(仅 4 权重蒙皮,无顶点 ID)在运行时不再使用,因为新文件优先。

02Special Projection Modes特殊投影模式

Mode模式MacroUse Case使用场景
IS_PARABOLOID#if IS_PARABOLOIDDual-paraboloid shadow maps for omni lights全向光源双抛物面阴影贴图
IS_SKYBOX#if IS_SKYBOXForce depth to far plane (z = w*0.9999)强制深度到远平面
TEXTURE_BAKE#if TEXTURE_BAKEUV-space rendering for lightmap bakingUV 空间渲染用于光照贴图烘焙
DEPTH_BIAS#if DEPTH_BIASManual depth offset (shadow bias) — now uses DepthBiasParam resource手动深度偏移;现使用 DepthBiasParam 资源
FOLIAGEIMPOSTER_ENABLED#if FOLIAGEIMPOSTER_ENABLEDNEW: Use imposter vertex transform for billboarded foliage新增:使用 Imposter 顶点变换实现告示板植被
PARTICLE_SYSTEM_GPU#if PARTICLE_SYSTEM_GPUNEW: Clip dead GPU particles in vs_main; cull in ps_main新增:在 vs_main 中剔除死亡 GPU 粒子
HLOD_BAKE#if HLOD_BAKENEW: Separate HLOD_Pixel output path for HLOD texture baking新增:用于 HLOD 纹理烘焙的独立输出路径

Pixel Shader Stage像素着色器阶段

The pixel shader is where all material evaluation and lighting happens. The flow follows a strict order:

像素着色器是所有材质计算和光照发生的地方。流程遵循严格顺序:

float4 ps_main(Fragment input, bool is_front_face : SV_IsFrontFace) : SV_Target0 {
  // 1. Setup
  Material mtl = (Material)0;
  View v;
  v.position = CameraPosition;
  v.direction = normalize(input.position_world - CameraPosition);
  v.distance = length(input.position_world - CameraPosition);

  // 2. Material setup (calls into material_*.hlsl)
  RawData raw_data = GetRawData(input);   // texture sampling
  SetupMaterial(input, raw_data, mtl);    // decode --> Material struct

  // 3. Lighting (calls into lighting.hlsl --> shading model)
  LightingResult result = Lighting(input, mtl, v);

  // 4. Compose final color
  float3 color = result.direct_diff + result.direct_spec
              + result.env_diff + result.env_spec
              + mtl.emissive;

  // 5. Tone mapping
  color = get_ACES_tone_mapping(color);

  return float4(color, opacity);
}

Lighting Loop — How Lights Are Evaluated光照循环 — 光源如何计算

Inside lighting.hlsl (1447 lines, new engine), the main lighting function iterates over all active lights. Point and spot lights are now unified under a single PunctualLighting() function with PunctualLightParams structs. Each light calls the active shading model's DirectLighting():

lighting.hlsl(新引擎 1447 行)中,主光照函数遍历所有活动光源。点光和聚光灯现在通过 PunctualLightParams 结构体统一到单个 PunctualLighting() 函数。每个光源调用当前着色模型的 DirectLighting()

Lighting(input, mtl, v) | +-- CalcLightingData(mtl, v, data_r) // precompute NdotV, spec, diff | +-- MainLighting() // directional (was ShadowLighting) | +-- CSM shadow (Render 3.0 sphere-cull) | +-- ENABLE_SSS_TRANSMITTANCE: CalcTransmittanceThickness | +-- SpecularScale from DirLightAttr[2].w (NEW) | +-- for each PunctualLight[i]: // unified point + spot | +-- GetPunctualLightParameter() // structured param access | +-- CalcPunctualLightAttenuation() // inv-sq + exponential falloff | +-- GetPunctualLightShadow() // point (cubemap) or spot | +-- PunctualLighting() // single function (was 4 functions) | +-- for each RectLight[i]: | +-- GetRectLightParameter() | +-- CalcRectLighting() // from rect_lighting.hlsl | +-- ApplyDeferredDecal() // NEW: tile-memory DBuffer decals | +-- EnvLighting(input, mtl, v, data_r, result) | +-- SH diffuse | +-- EnvironmentSpecular() // reflection probe + IBL | +-- EnvBRDFApprox() | +-- ApplyBentNormal() // NEW: SG-based AO occlusion | +-- AOMultiBounce() // NEW: multi-bounce colored AO | +-- return LightingResult { direct_diff *= INV_PI, direct_spec, env_diff, env_spec }
New vs replaced: The new lighting.hlsl replaces the old 1,982-line monolithic version. Old had 4 separate functions (PointLightingNonShadow, PointLightingShadow, SpotLightingNonShadow, SpotLightingShadow) → now unified into one PunctualLighting(). New additions: ENABLE_SSS_TRANSMITTANCE (Poisson-disk shadow depth for skin), ApplyBentNormal (SG-based AO), AOMultiBounce, ApplyDeferredDecal (tile-memory DBuffer). Cluster parameter naming changed from ClusterParam0-4 to semantic names. 新版替换:lighting.hlsl 替换了旧版 1,982 行的单体版本。旧版有 4 个独立光照函数(PointLightingNonShadow/ShadowSpotLightingNonShadow/Shadow)→ 现统一为 PunctualLighting()。新增功能:ENABLE_SSS_TRANSMITTANCE(泊松盘阴影深度用于皮肤)、ApplyBentNormal(SG AO)、AOMultiBounceApplyDeferredDecal(Tile 内存 DBuffer)。集群参数命名从 ClusterParam0-4 变更为语义化名称。

Special Modes特殊模式

Mode模式MacroWhat it does功能
SKIN4S_ENABLESKIN4S_SPECULARPASS4-pass SSS (split diffuse/specular); now encodes curvature into alpha channel4-Pass 次表面散射;现将曲率编码到 Alpha 通道
TOON_EFFECT#if TOON_EFFECTToon shading via Lerp3 color ramp通过 Lerp3 色阶实现卡通着色
IMAGE_DECAL_ENABLE#if IMAGE_DECAL_ENABLEApply projected image decals to GBuffer应用投影图片贴花到 GBuffer
ALPHA_TO_COVERAGE_ENABLE#if ALPHA_TO_COVERAGE_ENABLENEW: Analytic alpha-to-coverage via ddx/ddy for smooth edges新增:通过 ddx/ddy 实现解析 Alpha 覆盖,平滑边缘
INSTANCE_TRANSPARENCY#if INSTANCE_TRANSPARENCYNEW: Per-instance transparency via ClipIfPixelTransparent()新增:通过 ClipIfPixelTransparent() 实现逐实例透明
ENABLE_VIRTUALTEXTURE_SAMPLEING#if ENABLE_VIRTUALTEXTURE_SAMPLEINGNEW: Virtual texture streaming — SamplingVirtualTexture() before material setup; alternate output via WriteVirtualTexture()新增:虚拟纹理流式采样,材质初始化前调用;可通过 WriteVirtualTexture() 输出
USE_PIXEL_DEPTH_OFFSET#if USE_PIXEL_DEPTH_OFFSETNEW: Per-pixel depth offset (PDO) written to SV_Depth + tile memory新增:逐像素深度偏移,写入 SV_Depth 及 Tile 内存
USE_GAEA_COLOR_PICK#if USE_GAEA_COLOR_PICKNEW: GAEA terrain — write model type + instance ID for color picking新增:GAEA 地形——写入模型类型和实例 ID 用于颜色拾取
DEBUG_DATA#if DEBUG_DATAOutput material properties as color for debugging输出材质属性为颜色用于调试
RECORD_MODE#if RECORD_MODERecord rendering data for replay (now in separate Record_ForwardShading compositor)记录渲染数据用于回放(现在独立的 Record_ForwardShading 合成器中)
New vs replaced: The new forward_shading.hlsl adds: ALPHA_TO_COVERAGE_ENABLE, INSTANCE_TRANSPARENCY, ENABLE_VIRTUALTEXTURE_SAMPLEING, USE_PIXEL_DEPTH_OFFSET, USE_GAEA_COLOR_PICK, HLOD bake path. Removed from old version: EMISSIVE_CIRCADIAN, DISTANCE_OPACITY_ENABLE. NaN guard changed from conditional to unconditional -min(-pixel.Color, 0.0). RECORD_MODE moved to a separate Record_ForwardShading compositor (no longer inline). 新版替换:forward_shading.hlsl 新增:ALPHA_TO_COVERAGE_ENABLEINSTANCE_TRANSPARENCYENABLE_VIRTUALTEXTURE_SAMPLEINGUSE_PIXEL_DEPTH_OFFSETUSE_GAEA_COLOR_PICK、HLOD 烘焙路径。从旧版中移除:EMISSIVE_CIRCADIANDISTANCE_OPACITY_ENABLE。NaN 防护从条件改为无条件 -min(-pixel.Color, 0.0)RECORD_MODE 移到独立的 Record_ForwardShading 合成器(不再内联)。

Source Files源码文件

New vs replaced: The new forward_shading.render replaces the old one (which had ~65 macros and 13 shading models). POINT_LIGHTING_ENABLE + SPOT_LIGHTING_ENABLE unified to PUNCTUAL_LIGHTING_ENABLE. New compositors added: WaterSystem, NxParticle, Gpu_Particle_Compute, SSTDecode, FluidDepth. Stencil writing changed from enabled to disabled. All project-specific shaders in res/shader/ (buildings, ships, particles, etc.) remain accessible via fallback. 新版替换:forward_shading.render 替换旧版(旧版约 65 个宏和 13 种光照模型)。POINT_LIGHTING_ENABLE/SPOT_LIGHTING_ENABLE 统一为 PUNCTUAL_LIGHTING_ENABLE。新增合成器:WaterSystemNxParticleGpu_Particle_ComputeSSTDecodeFluidDepth。模板写入从启用改为禁用。res/shader/ 中的所有项目专用着色器(建筑、舰船、粒子等)通过回退机制仍然可用。