// Copyright UShaderLab. All Rights Reserved. #pragma once #include "CoreMinimal.h" class UMaterial; struct FShaderLabModel; /** * Turns a parsed FShaderLabModel into a UMaterial expression graph: property parameter nodes + a Custom * HLSL node for the Surface body wired into a Substrate Slab BSDF (-> FrontMaterial), plus an optional * Vertex Custom node for WPO/displacement/UVs. Lives in the UncookedOnly UShaderLabBuilder module, so it * runs in the editor AND under `-game` on uncooked data (not in cooked builds — see AIDoc §2.9). * * The build is fully deterministic for a given model (node creation order, input/output order, * generated HLSL) so the cook-time and editor-time graphs — and therefore the baked uniform * expression set — match. */ class USHADERLABBUILDER_API FShaderLabGraphBuilder { public: /** * Clear `Material`'s expression graph and rebuild it from `Model`, applying settings * (domain/blend/two-sided) and updating cached expression data. Does NOT trigger shader * compilation — callers decide when to compile. Returns false with diagnostics on failure. */ static bool BuildInto(UMaterial& Material, const FShaderLabModel& Model, TArray& OutErrors); /** * Replace `Material`'s graph with a minimal Substrate material whose single Custom node emits a * `#line`-mapped `#error` for `Diagnostics`, so it deliberately fails to compile with those messages * mapped back to `SrcPath` (an absolute, forward-slashed .usl path). This routes .usl parse/build * errors through the standard shader-compile path — MIC editor red text, GetCompileErrors, cook — * instead of dropping them. The graph itself is always valid; the failure is intentional and happens * at shader compile. Does NOT trigger compilation (the caller decides when). */ static void BuildPoisonInto(UMaterial& Material, const TArray& Diagnostics, const FString& SrcPath); /** * Resolve a virtual shader path ("/Project/Lib/X.uslfunc", "/Plugin/ShaderLab/...", "/Engine/...") to an * absolute disk path via the registered shader-source directory mappings (longest-prefix match, exact-root * allowed). Returns false if no mapping root contains the path. The single canonical reversal of the * shader-source mappings — used to load `.uslfunc` imports, by the editor hot-reload loader, and by the * VSCode button. (Forward direction: FShaderLabMaterialRegistry::MakeVirtualShaderPath.) */ static bool ResolveVirtualShaderFile(const FString& VirtualPath, FString& OutDiskPath); /** * Virtual shader root under which per-shader generated local-code headers live * (e.g. "/UShaderLabGen"). The editor module maps it to GetGeneratedShaderDir() at startup. */ static const TCHAR* GetGeneratedVirtualRoot(); /** * Absolute disk directory backing GetGeneratedVirtualRoot(): the plugin's * `Intermediate/ShaderLabGen`. A build-time artifact only (never staged into a pak); the cooked * runtime never builds graphs and skips the mapping. Empty string if the plugin can't be found. */ static FString GetGeneratedShaderDir(); };