Language Overview语言概览

NeoX shaders are written in a custom HLSL dialect that extends standard HLSL with engine-specific types, conventions, and cross-platform macros. The same source compiles to D3D11, OpenGL ES 3.0, and Metal via preprocessing.

NeoX 着色器使用自定义 HLSL 方言编写,在标准 HLSL 基础上扩展了引擎特定类型、约定和跨平台宏。同一份源码通过预处理编译为 D3D11、OpenGL ES 3.0 和 Metal。

Key difference from UE5: UE5 uses .usf/.ush files with a heavy macro layer (DECLARE_UNIFORM_BUFFER, FMaterialPixelParameters, etc.). NeoX uses cleaner, more direct HLSL — closer to what you'd write by hand — with struct-based interfaces (Material, View, Light, Fragment). 与 UE5 的关键差异:UE5 使用 .usf/.ush 文件配合厚重的宏层(DECLARE_UNIFORM_BUFFERFMaterialPixelParameters 等)。NeoX 使用更简洁、更直接的 HLSL——更接近手写——通过结构体接口(MaterialViewLightFragment)。

Core Data Types — The Four Struct Interface核心数据类型 — 四大结构体接口

All NeoX shaders communicate through four fundamental structs. This is the engine's "shader contract":

所有 NeoX 着色器通过四个基础结构体通信。这是引擎的"Shader 契约":

+=================================================================+ | NeoX Shader Data Flow | +=================================================================+ | | | +----------+ vs_main() +----------+ | | | Vertex | ===============>| Fragment | | | +----------+ +----+-----+ | | (input mesh) | | | v | | +--------------+ | | | ps_main() | | | +------+-------+ | | | | | +--------------+--------------+ | | v v v | | +----------+ +----------+ +----------+ | | | Material | | View | | Light | | | +----------+ +----------+ +----------+ | | albedo position direction | | normal direction color | | roughness distance attenuation | | metalness | | occlusion | | emissive | | shading_model | | | | +--------------+ | | |LightingResult| <== output | | +--------------+ | | direct_diff | | direct_spec | | env_diff | | env_spec | +=================================================================+
// Engine-provided structs (defined by pipeline)

struct Fragment {
  float4 position;           // SV_Position (clip space)
  float3 position_world;     // world-space position
  float4 position_screen;    // screen-space position
  float2 texcoord0;          // UV channel 0
  float3 normal_world;       // interpolated normal
  float3 tangent_world;      // interpolated tangent
  float3 binormal_world;     // interpolated binormal
};

struct Material {
  float3 albedo;             // base color (linear)
  float3 normal;             // world normal (after normal map)
  float  roughness;          // [0..1]
  float  metalness;          // [0..1]
  float  specular;           // specular intensity
  float  occlusion;          // ambient occlusion
  float3 emissive;           // self-illumination
  float3 tangent;            // for anisotropy / hair
  float4 sh;                 // spherical harmonics data
  uint   shading_model;      // enum: Isotropy, Skin, Hair...
  float  two_sided_sign;     // face direction sign
};

struct View {
  float3 position;           // camera world position
  float3 direction;          // normalized view direction
  float  distance;           // camera-to-pixel distance
};

struct Light {
  float3 direction;          // light direction (normalized)
  float3 color;              // light color * intensity
  float  attenuation;        // distance attenuation
};

Entry Points — vs_main / ps_main入口函数 — vs_main / ps_main

Every NeoX shader has two mandatory entry points. The vertex shader transforms geometry; the pixel shader evaluates materials and lighting:

每个 NeoX 着色器有两个必需入口点。顶点着色器变换几何体;像素着色器计算材质和光照:

// Vertex Shader (from forward_shading.hlsl)
Fragment vs_main(Vertex input) {
  Fragment frag = (Fragment)0;
  CommonVertex vert = TransformCommonVertex(input, vert_inter);
  
  ApplyVertexOffsetLocal(vert, vert.position);
  #if GPU_SKIN_ENABLE
    DoSkin(vert.blendWeights, vert.blendIndices, ...);
  #endif
  
  float4 world_position = Transform(vert.world_mat, vert.position);
  SetupFragment(vert, vert_inter, mtl_vtx_params, world_position, frag);
  return frag;
}

// Pixel Shader
float4 ps_main(Fragment input, bool is_front_face : SV_IsFrontFace) : SV_Target0 {
  Material mtl = (Material)0;
  View v = (View)0;
  v.position = CameraPosition;
  v.direction = normalize(input.position_world - CameraPosition);
  
  RawData raw_data = GetRawData(input);   // sample textures
  SetupMaterial(input, raw_data, mtl);    // fill Material struct
  
  // ... lighting calculation ...
  return final_color;
}

Cross-Platform Macros跨平台宏

NeoX targets three graphics APIs from a single source. Platform differences are resolved via these macros:

NeoX 从单一源码目标化三种图形 API。平台差异通过以下宏解决:

Macro Meaning含义 Use Case使用场景
NEOX_GLSLCompiling for OpenGL ES编译为 OpenGL ESUV Y-flip, depth range [0,1] vs [-1,1]UV Y翻转、深度范围差异
NEOX_METALCompiling for Metal编译为 MetalBuffer layout, texture access patternsBuffer 布局、纹理访问模式
GPU_SKIN_ENABLEGPU skinning activeGPU 蒙皮激活Bone transform in vertex shader顶点着色器中骨骼变换
NORMAL_MAP_ENABLENormal map bound法线贴图已绑定TBN transform for normal decoding法线解码的 TBN 变换
LIGHT_ENABLELighting active光照激活Include lighting.hlsl包含 lighting.hlsl
SHADOW_MAP_ENABLEShadow mapping active阴影贴图激活Include shadow.hlsl, sample shadow map包含 shadow.hlsl、采样阴影贴图
INSTANCE_TYPEInstancing mode实例化模式NONE / PRS / PRS_LM / VEGETATION / SKINNING
LOD_LEVELQuality LOD tier品质 LOD 层级Controls IBL, reflection probe quality控制 IBL、反射探针品质
// Platform-specific depth handling example
#ifdef NEOX_GLSL
  float depth = -(2 * output.z - 1);      // GL: [-1,1] range
#else
  float depth = 1 - output.z;              // D3D: [0,1] range
#endif

// Screen UV Y-flip for D3D
#ifndef NEOX_GLSL
  input.position_screen.y = 1 - input.position_screen.y;
#endif

Include Hierarchy包含层级

NeoX shaders follow a strict include hierarchy. Understanding this tree is essential for navigation:

NeoX 着色器遵循严格的包含层级。理解这棵树对导航至关重要:

forward_shading.hlsl (or deferred_shading_gbuffer.hlsl) +-- built_in/shadow/shadow.hlsl // shadow sampling +-- built_in/common/decal.hlsl // deferred decal application +-- built_in/common/lighting.hlsl // 1982 lines, the lighting core | +-- built_in/common/function.hlsl // 782 lines, math utilities | +-- built_in/brdf/ggx/brdf.hlsl // BRDF functions | +-- built_in/shading_models/ // per-model lighting | +-- isotropy.hlsl | +-- skin.hlsl | +-- hair.hlsl | +-- clearcoat.hlsl | +-- toon.hlsl | +-- ... (13 models total) +-- built_in/debug/debug.hlsl // debug visualization material_*.hlsl (per-material code) +-- built_in/materials/material_common.hlsl // shared material interface

Utility Library — function.hlsl (782 lines)工具函数库 — function.hlsl (782 行)

The function.hlsl library provides optimized math primitives used throughout the entire shader codebase:

function.hlsl 库提供整个着色器代码库中使用的优化数学原语:

Category类别 Functions函数 Description说明
Power幂运算Pow2, Pow3, Pow4, Pow5Faster than pow() — unrolled multiplies比 pow() 更快——展开乘法
Fast trig快速三角acosFast, asinFast, atanFastPolynomial approximations (max error <0.01)多项式近似(最大误差 <0.01)
Color space色域转换srgb2linear, linear2srgb, RGB2HSV, HSV2RGBGamma/linear conversion, hue manipulationGamma/线性转换、色相操作
Normal encoding法线编码6 schemes: Octahedron, Paraboloid...6 种方案GBuffer packing for deferred path延迟路径的 GBuffer 打包
Bit packing位打包PackFloatToRGBA, PackHalfFloatEncode float to RGBA8 for mobile浮点编码为 RGBA8 用于移动端
Dither抖动Dither16, Dither32, Dither64, Dither17Bayer matrix patterns for alpha ditheringBayer 矩阵图案用于 Alpha 抖动
Depth深度重建GetViewPositionFromDepthReconstruct view-space position from depth从深度重建视空间位置