中EN

How the Unreal Engine Translates a Material Graph to HLSL

  • After Apply in Material Editor: (1) translate material graph to HLSL; (2) compile HLSL to GPU bytecode. Article focuses on (1). Shader permutations: not one shader per material — several depending on features/platforms/usages; see Understanding Shader Permutations (linked from article; separate fetch redirected to docs home).
  • View generated shader: Window → Shader Code → HLSL Code (read-only). Copy to Notepad++/Rider/VS with HLSL highlighting.
  • Template: Engine/Shaders/Private/MaterialTemplate.ush — structures/functions with "%s" placeholders filled by text replacement. Called from pixel shader BasePassPixelShader.usf.
  • Filled by FMaterialCompiler; standard path uses FHLSLMaterialTranslator (inherits FMaterialCompiler). Also Lightmass / Proxy implementations.

Call path

FMaterial::CacheShaders

  • FMaterial::BeginCompileShaderMap

    • FHLSLMaterialTranslator::Translate
    • FHLSLMaterialTranslator::GetMaterialEnvironment
    • FHLSLMaterialTranslator::GetMaterialShaderCode
    • FPartialShaderMap::Compile
  • Translate: prepare each material input pin's graph; ensure vertex interpolators, texture coordinates, material parameter collections, virtual texture samples, etc.; error reporting (e.g. per-pixel shading models with SingleLayerWater).

  • GetMaterialEnvironment: sets defines used in final HLSL (#ifdefs for shading models / features).

  • GetMaterialShaderCode: prints compiled data into template string.

UMaterialExpression::Compile

  • Nodes inherit UMaterialExpression; key methods Compile, GetCaption, GetKeywords. Declarations in headers; definitions in Engine/Source/Runtime/Engine/Private/Materials/MaterialExpressions.cpp. Each can define constants and FExpressionInput graph inputs.
  • Compile returns int32 = array index of compiled result. Takes FMaterialCompiler*.
  • Example UMaterialExpressionAdd::Compile: if pin connected compile input else Compiler->Constant(ConstA/ConstB); then Compiler->Add(...).

Constant Folding (FHLSLMaterialTranslator::Add)

  • Both constant → precompute on CPU, write literal result.
  • One constant + parameter → hidden parameter combining them on CPU so GPU sees a fixed number.
  • Both non-constant → emit "A + B".
  • Example graph outcomes in CalcPixelMaterialInputs:
    • Roughness: PixelMaterialInputs.Roughness = (1.00000000 + 2.00000000);
    • Metallic: Material.ScalarExpressions[0].z (packed float4 uniform expressions)
    • Base Color: MaterialFloat Local1 = (Parameters.TexCoords[0].xy.r + Material.ScalarExpressions[0].y); then PixelMaterialInputs.BaseColor = Local1;
  • Non-constant results stored as LocalN variables; hashed so duplicate subgraphs reuse LocalN.

EmissiveColor editor quirk

  • Editor-compiled materials lerp user emissive with a VectorExpression controlled by engine value for selection highlighting; optimized away in cooked shaders.

References cited in article

  • Tim Jones Shader Playground; Rider HLSL; Notepad++ HLSL UDL; UE4 Rendering Part 4 Deferred; HLSL Tools for VS (add .usf/.ush extensions).

引用这一章的笔记

输入关键词开始搜索

滚轮或双指缩放 · 拖动平移 · 双击放大 / 还原