// Copyright UShaderLab. All Rights Reserved. // // ShaderLab DSL vocabulary — the UFUNCTION/UPROPERTY-style annotation macros that mark up an // otherwise-plain-HLSL `.usl` file. Every macro expands to NOTHING for the preprocessor (and for // HLSL Tools / Rider), so the file stays valid HLSL and gets free completion; the ShaderLab C++ // parser reads these macro invocations + the HLSL declaration that follows to rebuild its model. // // Included (transitively, via ShaderLab.ush) by every `.usl`. This file is static and checked in; // the sibling ShaderLab.ush is generated by the `ShaderLab.IDE.Prepare` console command. #pragma once // --------------------------------------------------------------------------- // Annotation macros. Two-line UFUNCTION style: the macro sits on its own line // directly above the HLSL declaration it annotates. // --------------------------------------------------------------------------- // Material settings. Standalone (no following declaration). // SL_SETTINGS(Domain = Surface, BlendMode = Opaque, TwoSided = false, OpacityMaskClipValue = 0.4) #define SL_SETTINGS(...) // Material parameter. Precedes the HLSL declaration whose type selects the DSL type: // float -> Scalar | float3 -> Color | float4 -> Vector | // Texture2D/TextureCube -> texture | "#define X v" -> StaticBool. // Scalar/Color/Vector defaults come from the HLSL initializer; texture default from DefaultTexture. #define SL_PROPERTY(...) // Function-library import. Annotates the `#include "...uslfunc"` on the NEXT line, carrying options such // as Namespace= (prefixes the promoted parameters so same-named properties across libraries stay distinct). // A plain `#include "...uslfunc"` (no marker) imports with default by-name merging. // SL_IMPORT(Namespace = "Detail") // #include "/Project/Lib/DetailLib.uslfunc" #define SL_IMPORT(...) // Material Parameter Collection read. Precedes a `floatN ;` declaration; reads a global MPC value // (not a per-instance knob). Path is the collection asset; optional Parameter overrides the in-collection name. // SL_COLLECTION(Path = "/Game/MPC/MPC_Weather", Parameter = "WindVector") // float3 WindVector; #define SL_COLLECTION(...) // Pre-sampled streaming Virtual Texture read. Precedes a `float4 ;` declaration; the body uses // directly as the sampled color (a VT cannot be sampled inside a Custom node, so the graph builder samples it // with a real node and feeds the result in). SamplerType defaults to VirtualColor. UV selects the coordinate. // SL_VTSAMPLE(DefaultTexture = "/Game/VT/T_Albedo", SamplerType = VirtualColor, UV = TexCoord0) // float4 VTAlbedo; #define SL_VTSAMPLE(...) // Pre-sampled Runtime Virtual Texture read. Precedes an `FShaderLabRVT ;` declaration; the body reads // channels via .BaseColor / .Normal / .Roughness / ... (see FShaderLabRVT in ShaderLabCommon.ush). // MaterialType selects the RVT layout; UV = World derives the coordinate from world position. // SL_RVTSAMPLE(VirtualTexture = "/Game/RVT/RVT_Terrain", MaterialType = BaseColor_Normal_Roughness, UV = World) // FShaderLabRVT Terrain; #define SL_RVTSAMPLE(...) // Runtime Virtual Texture WRITE. An additive output block (alongside the pixel entry) that fills the channels // written into an RVT when the mesh renders into it. Precedes a `void (inout FShaderLabRVTOutput O){...}`. // SL_RVTOUTPUT() void RVTOutput(inout FShaderLabRVTOutput O) { O.BaseColor = ...; O.Normal = ...; } #define SL_RVTOUTPUT(...) // Library function (`.uslfunc` files only). Precedes a normal HLSL function; it may use UE_ intrinsics, // reference the library's own properties, and call other library functions. // SL_FUNCTION() // float3 ApplyDetail(float3 baseColor, float2 uv) { ... } #define SL_FUNCTION(...) // Pixel/vertex entry points. Precede a `void Name(inout F... X) { ... }` (Vertex takes FShaderLabVertex). // Optional material context: to call the UE_Transform* helpers (which need the material `Parameters`), add // a leading `FMaterialPixelParameters Parameters` (pixel entries) or `FMaterialVertexParameters Parameters` // (SL_VERTEX) BEFORE the output-struct parameter, named literally `Parameters`, e.g. // SL_SURFACE() void Surface(FMaterialPixelParameters Parameters, inout FShaderLabSurface S) { ... } #define SL_SURFACE(...) #define SL_POSTPROCESS(...) #define SL_UI(...) #define SL_VERTEX(...) // Additional Substrate BSDF entries. Each precedes a `void Name(inout F X) { ... }` whose output struct // is the matching FShaderLab (see ShaderLabCommon.ush). Used either as the sole entry (whole material = // that BSDF) or as a named block referenced by SL_FRONTMATERIAL. Composition legality is enforced by the // builder (mirroring Substrate's operator allow-lists). SL_VOLUME requires Domain = Volume; SL_LIGHTFUNCTION // requires Domain = LightFunction; the rest are Surface-domain BSDFs. #define SL_UNLIT(...) // void Name(inout FShaderLabUnlit U) #define SL_HAIR(...) // void Name(inout FShaderLabHair H) #define SL_EYE(...) // void Name(inout FShaderLabEye E) #define SL_WATER(...) // void Name(inout FShaderLabWater W) #define SL_CLEARCOAT(...) // void Name(inout FShaderLabClearCoat C) #define SL_TOON(...) // void Name(inout FShaderLabToon T) #define SL_VOLUME(...) // void Name(inout FShaderLabVolume V) — Domain = Volume #define SL_LIGHTFUNCTION(...) // void Name(inout FShaderLabLightFunction L) — Domain = LightFunction // Multi-slab building blocks. #define SL_SLAB(...) // precedes `void Name([FMaterialPixelParameters Parameters,] inout FShaderLabSlab S) { ... }` #define SL_VALUE(...) // precedes `float Name([FMaterialPixelParameters Parameters]) { return ; }` #define SL_FRONTMATERIAL(...) // standalone: SL_FRONTMATERIAL(VerticalLayer(Coat, Metal, Thickness)) // Material-level (whole-material) pixel-stage outputs for a multi-slab shader. Precedes a // `void Name([FMaterialPixelParameters Parameters,] inout FShaderLabMaterialOutput O) { ... }`. Writing the // fields it needs (O.Opacity / O.OpacityMask / O.Refraction / O.PixelDepthOffset / O.AmbientOcclusion / // O.SurfaceThickness) is the multi-slab counterpart of setting S. in a single SL_SURFACE: one Custom // node feeds all of them (shared computation). At most one per shader; not allowed together with SL_SURFACE // (a single Surface already carries these fields). #define SL_MATERIAL(...) // precedes `void Name([FMaterialPixelParameters Parameters,] inout FShaderLabMaterialOutput O) { ... }` // Vertex Interpolator: precedes `floatN Name([FMaterialVertexParameters Parameters]) { return ; }` // — a value computed per-vertex and interpolated to the pixel shader (backed by a UMaterialExpressionVertexInterpolator). // Read it in a pixel body with `UE_Interpolator(Name)`, or use a scalar one as a topology mix factor. #define SL_INTERPOLATOR(...) // IDE-only: `UE_Interpolator(Name)` reads the interpolator's value. In the editor it expands to a direct // call of the (real HLSL) interpolator function so completion/type-checking work; at real compile this // authoring shim is stripped by the parser and the graph builder rewrites the call into a node input. #ifndef UE_Interpolator #define UE_Interpolator(Name) (Name()) #endif // --------------------------------------------------------------------------- // Specifier vocabulary (canonical, PascalCase — aligned with UE conventions). // These are the keys accepted inside the macros above. // // SL_SETTINGS : Domain, BlendMode, TwoSided, OpacityMaskClipValue, // Domain = Surface | PostProcess | UI | Decal // BlendMode = Opaque | Masked | Translucent | Additive | Modulate // SL_PROPERTY : Category, SortPriority, DefaultTexture (textures only), // SamplerType (textures only: Color|LinearColor|Normal|Grayscale|LinearGrayscale|Masks|Alpha| // DistanceFieldFont|Data; Virtual* is rejected — use SL_VTSAMPLE), // ClampMin / ClampMax (Scalar slider bounds; each independent), // CustomPrimitiveData = (Scalar/Vector only; per-instance via Custom Primitive Data; // mutually exclusive with ClampMin/ClampMax) // SL_VTSAMPLE : DefaultTexture, SamplerType (Virtual* only; default VirtualColor), UV // SL_RVTSAMPLE: VirtualTexture, MaterialType, UV // UV (VT/RVT) : TexCoord (a texcoord set) | | World (RVT only) // // Topology operators (used inside SL_FRONTMATERIAL): // VerticalLayer(Top, Base, Thickness) | HorizontalMix(Background, Foreground, Mix) // Add(A, B) | Weight(A, Weight) | Select(A, B, Threshold) // A mix factor is a float literal, a Scalar property name, or an SL_VALUE block name. // ---------------------------------------------------------------------------