Skip to content

Built-in Passes and Shader Macros ​

Pure quick reference: built-in passes, shader macros, attribute locations, engine-provided uniforms, and dialect rules. Keep it open as a dictionary while writing custom passes.

Built-in pass inventory ​

Shared passes (Aura3D.Core) ​

PassWhat it doesGroupPipelines
BackgroundPassDraws the background: solid color / texture / skyboxEveryCameraAll built-in pipelines
ShadowMapPassDepth pre-pass producing shadow maps for all shadow-casting lightsOnce (once per frame)BlinnPhong / PBR Deferred / PBR Forward / CelShading
LightPassBlinn-Phong forward main lighting: opaque + Masked, split into static / skinned / instanced passesEveryCameraBlinnPhong. The most common material-override pass key (ShaderName is "LightPass")
TranslucentPassTranslucent meshes (back-to-front sorted, then blended); derives from LightPassEveryCameraBlinnPhong
ParticlePassBillboard particle rendering; mesh-mode emitters render as InstancedMesh through the main lighting passesEveryCameraBlinnPhong / PBR Deferred / PBR Forward / CelShading
GammaCorrectionPassLinear → sRGB output (full-screen quad)EveryCameraBlinnPhong / NoLight / PointCloud / CelShading / PBR (after ToneMapping)
FxaaPassFXAA post-process anti-aliasing; with Settings.EnableFxaa = false it switches to the FXAA_DISABLED passthrough variantEveryCameraAll built-in pipelines (outputs to CameraOutput)
ToneMappingPassACES tone mapping consuming ToneMappingExposure and BrightnessClampEveryCameraPBR Deferred / PBR Forward
CopyPassFull-screen texture copy moving one RenderTarget's color texture into another (e.g. compositing the lighting result onto the background target in PBR deferred)EveryCameraPBR Deferred
DebugDrawPassDebug wireframe overlay: bounding boxes, light shapes, frustums, bones; driven by Settings.Debug.*EveryCameraAll pipelines (auto-registered via RegisterDebugPass)
NoLightPassUnlit output of the material colorEveryCameraNoLightPipeline
PointCloudPassInstanced point-cloud rendering (gl_PointSize + per-instance attribute shading)EveryCameraPointCloudPipeline

Pipeline-specific passes ​

PassPackage / pipelineWhat it does
BasePassAura3D.Pipeline.PBR (PBR Deferred)Writes materials into the GBuffer (BaseColor / NormalRoughness / MetallicEmissive as three RGBA8 attachments + depth)
IBLAmbientPass / ConstantAmbientPassAura3D.Pipeline.PBRAmbient term of the deferred lighting: IBL convolved environment / constant ambient
DirectionalLightingPass / PointLightingPass / SpotLightingPassAura3D.Pipeline.PBRFull-screen deferred lighting, one light type per pass
TranslucentPass / TranslucentIBLAmbientPass / TranslucentConstantAmbientPassAura3D.Pipeline.PBRThe forward supplemental lighting chain for translucency
IrradianceMapPass / PrefilteredEnvironmentMapPassAura3D.Pipeline.PBR.CommonConvolves the HDR environment into the irradiance map and the prefiltered environment map (lazy IBL generation)
CelLightPass / OutlinePass / CelTranslucentPassAura3D.Pipeline.CelShadingToon main lighting / outlines / toon translucency

Registration order and data flow per pipeline: Choosing and Configuring Pipelines; writing your own RenderPass subclass: Custom Render Pipelines.

The shader-macro system ​

Injection point and flow ​

Every built-in GLSL carries a // line — when a variant is compiled, the engine expands the current defines list into #define X lines and replaces that comment in place (in both the vertex and the fragment source). Without the line, passing macros has no effect.

MethodWhat it doesTouches the GPU
UseShader(params string[] defines)Replaces the current defines listNo
AddDefines(params string[] defines)Appends to the current listNo
RemoveDefines(params string[] defines)Removes from the listNo
UseShader_Internal()Compiles / fetches the cached variant for the current list and calls glUseProgramYes

RenderVisibleMeshesInCamera and friends call UseShader_Internal automatically before each mesh; post-process passes that don't iterate meshes must call it manually before RenderQuad(). The cache key is the defines joined with ; in order — a different order is a different variant, so declare all macros in one UseShader call. UseShader/AddDefines must run before UseShader_Internal, otherwise the previous frame's variant gets bound (an empty first frame).

Macro names in actual use ​

All of the following appear verbatim in the engine source (keep the exact spelling and case):

MacroInjected byWhat it does
SKINNED_MESHLightPass / TranslucentPass / ShadowMapPass / NoLightPass / Cel / PBR passesSkinning branch: deforms vertices from the BoneMatrices UBO (MAX_BONES 256)
INSTANCED_MESHEvery pass that supports instancingmodelMatrix / normalMatrix switch from uniforms to per-instance vertex attributes (locations 8–11 / 12–15)
BLENDMODE_MASKEDLightPass / ShadowMapPass / NoLightPass / Cel / PBR BasePassAlpha cutout: discard when alpha ≤ alphaCutoff
BLENDMODE_TRANSLUCENTTranslucentPass / NoLightPass / PointCloudPass / Cel / PBRTranslucent branch
ENABLE_CSMBlinnPhong LightPass (when a main directional light is set), PBR DirectionalLightingPassThe main directional light samples cascaded shadow maps
ENABLE_SHADOWSPBR Deferred lighting passesThis light type samples its shadows
ENABLE_DIR_LIGHT / ENABLE_POINT_LIGHT / ENABLE_SPOT_LIGHTPBR Deferred / PBR Forward lighting and translucent passesThe full-screen lighting pass computes only this light type
ENBALE_DEFERRED_SHADINGPBR Deferred (IBLAmbientPass, ConstantAmbientPass, the lighting passes)The GBuffer-reading deferred-lighting variant. Note this is the source spelling — "ENBALE", one letter short of "ENABLE". Copy it exactly; do not "fix" it
IS_FIRST_LIGHTPBR TranslucentConstantAmbientPassFirst-term handling in the multi-light translucent accumulation order
FACE_RENDERCelShading CelLightPassFace-specific toon lighting variant
SKYBOX / ORTHOGRAPHIC / BACKGROUND_TEXTUREBackgroundPassSkybox / skybox under an orthographic camera / textured background variants
PARTICLE_OPAQUE / PARTICLE_MASKED / PARTICLE_TRANSLUCENTParticlePassPicks the particle variant per emitter BlendMode
PARTICLE_TEXTURE / PARTICLE_FLIPBOOKParticlePassSamples the particle texture / additionally indexes flipbook tiles
FXAA_DISABLEDFxaaPassPassthrough copy when anti-aliasing is off

Additionally, the built-in shaders' headers define compile-time constants MAX_BONES, MAX_DIRECTIONAL_LIGHTS / MAX_POINT_LIGHTS / MAX_SPOT_LIGHTS (default 4). Changing the three light limits in PipelineSettings makes LightPass rewrite those #define lines by string replacement — which is why the limits must be set before the pipeline is created.

Vertex and instance attribute location convention ​

One rule: in GLSL, layout(location = N)'s N is the numeric value of the BuildInVertexAttribute enum. The engine binds the VAO with the enum value directly — there is no remapping.

Enum memberlocationNotes
Position0Vertex position (vec3)
TexCoord_01Primary UV
Color_02Vertex color (vec4)
Normal3Normal
Tangent4Tangent
Bitangent5Bitangent
Joints_06Bone indices
Weights_07Bone weights
InstancedTransformColumn0..38–11The per-instance modelMatrix under INSTANCED_MESH (a mat4 occupies 4 locations)
InstancedNormalTransformColumn0..312–15The per-instance normalMatrix under INSTANCED_MESH
TexCoord_116Free slot (the usual choice for a per-instance custom attribute, e.g. a vec4 instance color)
TexCoord_217Free slot
TexCoord_318Free slot
Joints_119Reserved for extended skinning data
Weights_120Reserved for extended skinning data

WARNING

For a custom per-instance attribute, the location declared in the shader must equal the numeric value of the enum member you passed (e.g. SetInstanceAttribute<Vector4>(BuildInVertexAttribute.TexCoord_1, 4, …) pairs with layout(location = 16) in vec4 instanceColor;). Don't guess the number from memory.

Conventions worth knowing:

  • Built-in attributes with location ≤ 7 are enabled by default; switch off what you don't need via geometry.SetAttributeEnabled(BuildInVertexAttribute.TexCoord_1, false) to save bandwidth. On the instance side, instancedMesh.SetAttributeEnabled("InstanceNormalTransform", false) frees locations 12–15.
  • In the INSTANCED_MESH variant modelMatrix is a per-instance vertex attribute (8–11), not a uniform — the two declarations are picked by an #ifdef INSTANCED_MESH branch, as every built-in shader does.
  • Once you override the vertex shader, nobody multiplies the instance matrix for you: declare it at location 8 inside the #ifdef INSTANCED_MESH branch and multiply it in yourself (see the Gallery's Kit/Shaders.cs).

Uniforms the engine always provides ​

Uniform nameProvided byNotes
modelMatrix / viewMatrix / projectionMatrixBound automatically by the render methodsUnder the instanced variant, modelMatrix becomes a vertex attribute
cameraPositionThe cameraFor parallax / environment sampling
alphaCutoffThe material's AlphaCutoffUsed in the BLENDMODE_MASKED branch
BaseColorTexture / NormalTexture and friendsMaterial channelsChannel BaseColor → sampler BaseColorTexture (PBR channels follow the same naming convention)
Any custom namematerial.SetParameterValue(name, value)Binds by name to the same-named uniform in the GLSL

Shader dialect (ShaderDialect) ​

In one sentence: all built-in and custom shaders are written as GLSL ES 3.0 (#version 300 es); the dialect is chosen automatically at runtime from the context — an ES context compiles the source as-is, a desktop GL context swaps #version 300 es for #version 410 core and strips every precision declaration (so desktop requires GL 4.1+; macOS only offers desktop GL and always takes this branch).

The built-in shader sources live in src/Aura3D.Core/Assets/Shaders/ and are exposed through ShaderResource as MeshVert/MeshFrag (base.vert/base.frag), BackgroundVert/Frag, ShadowMapVert/Frag, NoLightVert/Frag, DebugVert/Frag; the GLSL for FXAA, Gamma, ToneMapping, Copy, Particle and PointCloud is embedded in the respective pass classes.