Files
UShaderLab/Shaders/Private/ShaderLabDSL.ush
Eragon-Brisingr e76eb856f5 Support all BSDF
2026-07-03 11:56:30 +08:00

109 lines
6.8 KiB
Plaintext

// 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 <Name>;` 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(...)
// 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<Bsdf> X) { ... }` whose output struct
// is the matching FShaderLab<Bsdf> (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 FShaderLabSurface S) { ... }`
#define SL_VALUE(...) // precedes `float Name([FMaterialPixelParameters Parameters]) { return <float>; }`
#define SL_FRONTMATERIAL(...) // standalone: SL_FRONTMATERIAL(VerticalLayer(Coat, Metal, Thickness))
#define SL_OPACITY(...) // standalone: SL_OPACITY(SomeValueName)
#define SL_OPACITY_MASK(...) // standalone: SL_OPACITY_MASK(SomeValueName)
#define SL_REFRACTION(...) // standalone: SL_REFRACTION(SomeValueName) — feeds the material Refraction pin
#define SL_PIXEL_DEPTH_OFFSET(...)// standalone: SL_PIXEL_DEPTH_OFFSET(SomeValueName) — feeds the material PixelDepthOffset pin
// Vertex Interpolator: precedes `floatN Name([FMaterialVertexParameters Parameters]) { return <vertex HLSL>; }`
// — 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, <reflection-allowlist keys...>
// Domain = Surface | PostProcess | UI | Decal
// BlendMode = Opaque | Masked | Translucent | Additive | Modulate
// SL_PROPERTY : Category, SortPriority, DefaultTexture (textures only),
// ClampMin / ClampMax (Scalar slider bounds; each independent),
// CustomPrimitiveData = <index> (Scalar/Vector only; per-instance via Custom Primitive Data;
// mutually exclusive with ClampMin/ClampMax)
//
// 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.
// ---------------------------------------------------------------------------