Shader Material Sections
Material shaders are special and require additional sections to expose parameters to the engine and editor. A material shader typically includes all three sections shown below:
[MATERIALCONSTANTS]
COLOR4F(BaseColor);
[MATERIALPARAMETER]
Permutation BLEND_MODE;
Color BaseColor @Default(Color(1.0, 1.0, 1.0));
Texture2D BaseTexture @Default("{ ac614d7c-2b31-4a7b-aa0c-c5d8200b7b89 }");
[MATERIALCONFIG]
#if (BLEND_MODE == BLEND_MODE_OPAQUE)
RenderDataCategory = LitOpaque
#elif (BLEND_MODE == BLEND_MODE_MASKED)
RenderDataCategory = LitMasked
#else
RenderDataCategory = LitTransparent
#endif
[PIXELSHADER]
Texture2D BaseTexture;
SamplerState BaseTexture_AutoSampler;
float4 main(VS_OUT a) : SV_Target
{
float4 color = BaseTexture.Sample(BaseTexture_AutoSampler, ...).rgba;
return color * GetMaterialData(BaseColor).rgba;
}
MATERIALCONSTANTS
This section defines per-material constants. The constants map to a constant buffer or structured buffer in the engine, depending on the renderer feature set. They can be changed at runtime for each material instance and exposed to the editor.
Constants must be declared using the macros defined in Data/Base/Shaders/Common/ConstantBufferMacros.h, e.g. FLOAT1(ConstantName);. Only these macros are supported:
FLOAT1,FLOAT2,FLOAT3,FLOAT4: Maps to HLSLfloat,float2etc.INT1,INT2,INT3,INT4: Maps to HLSLint,int2etc.UINT1,UINT2,UINT3,UINT4: Maps to HLSLuint,uint2etc.MAT3,MAT4: Maps to HLSLfloat3x3andfloat4x4.TRANSFORM: Maps to a struct with three rowsr0,r1andr2(no direct HLSL equivalent).COLOR4F: Maps tofloat4(no color type exists in HLSL).BOOL1: The HLSLboolis always 4 bytes wide. Consider packing multiple flags into aUINT1to save space.
To access a constant in the shader, use GetMaterialData(ConstantName).
MATERIALPARAMETER
This section defines which parameters are exposed on a material in the editor. There are three categories:
Permutation variables: Add the name of a permutation variable to expose it in the editor. See Shader Permutation Variables for details.
Material constants: These must match the name used in
MATERIALCONSTANTSexactly. The type changes from the macro name to the HLSL name, e.g.FLOAT1(MaskThreshold);becomesfloat MaskThreshold @Default(0.25);.Textures: Both
Texture2DandTextureCubeare supported, using the same syntax as HLSL texture declarations.
Parameters support the following attributes:
@Default(<VALUE>): Sets the default value shown in the editor. Usable on constants and textures.@Clamp(min, max): Restricts the range of float and int parameters in the editor.
MATERIALCONFIG
This section controls when a material is rendered during a frame by assigning a RenderDataCategory. The category determines which render passes process the material, how objects using it are sorted, and how it integrates into the rendering pipeline.
Default Category Assignment
Most materials use the default mapping provided by MaterialConfig.h:
[MATERIALCONFIG]
#include <Shaders/Materials/MaterialConfig.h>
This automatically assigns categories based on BLEND_MODE:
BLEND_MODE_OPAQUE→LitOpaqueBLEND_MODE_MASKEDorBLEND_MODE_DITHERED→LitMasked- All others (TRANSPARENT, ADDITIVE, MODULATE) →
LitTransparent
You can override this by setting the category explicitly:
[MATERIALCONFIG]
RenderDataCategory = SimpleForeground
Available Render Data Categories
Lit Categories (Full PBR Lighting)
These categories render with complete lighting calculations including direct lights, shadows, and image-based lighting.
LitOpaque — Use for solid, opaque materials. Renders in the depth pre-pass and opaque forward pass. Sorted front-to-back for optimal depth rejection. Automatically redirected to
LitOpaqueStaticorLitOpaqueDynamicbased on whether the object is static or dynamic.LitMasked — Use for materials with binary alpha cutout, such as foliage, chain-link fences, or grates. Similar to
LitOpaquebut uses alpha testing to discard pixels. Writes to the depth buffer. Redirected toLitMaskedStaticorLitMaskedDynamic.LitTransparent — Use for alpha-blended transparent materials like glass, water, or particles. Renders after opaque geometry. Sorted back-to-front for correct blending. Does not write to the depth buffer.
LitForeground — Use for transparent materials that must appear in front of regular transparent geometry. Renders after
LitTransparent.LitScreenFX — Use for screen-space effects with lighting.
Simple Categories (Unlit Rendering)
These categories skip lighting calculations. Useful for debug visualization, editor tools, and effects that should not be affected by scene lighting or tonemapping.
- SimpleOpaque — Unlit opaque geometry. Renders after lit passes. Sorted front-to-back.
- SimpleTransparent — Unlit transparent geometry. Renders after
SimpleOpaque. Sorted back-to-front. - SimpleForeground — Debug overlays and 3D UI elements. Renders last among simple categories to appear on top of other geometry.
Special Categories
- Sky — For skybox and sky dome materials. Renders after the opaque forward pass to fill the background.
- GUI — For UI rendering.
Static vs Dynamic Redirection
LitOpaque and LitMasked are redirected categories: at runtime, the engine automatically redirects them to their static or dynamic variants based on object flags.
- LitOpaque → LitOpaqueStatic or LitOpaqueDynamic
- LitMasked → LitMaskedStatic or LitMaskedDynamic
Shader authors should always use LitOpaque and LitMasked in the MATERIALCONFIG section. Do not use the Static/Dynamic variants directly.
Rendering Pipeline Order
Materials are rendered in the following order each frame:
- Depth Pre-Pass (optional):
LitOpaqueStatic,LitOpaqueDynamic,LitMaskedStatic,LitMaskedDynamic - Opaque Forward:
LitOpaqueStatic,LitOpaqueDynamic,LitMaskedStatic,LitMaskedDynamic - Sky:
Sky - Transparent Forward:
LitTransparent,LitForeground,LitScreenFX - Simple:
SimpleOpaque,SimpleTransparent,SimpleForeground - GUI:
GUI