Shader Uniform Reference
The exact uniform names the built-in pipelines upload, so a custom shader or effect can declare the ones it consumes and inherit the rest of the scene data.
The contract is what the pipeline resolves and uploads (the F# side), not what the shipped GLSL/HLSL happens to declare. Sources of truth:
Mibo.Raylib/Graphics3D/Pipelines/SceneUpload.fs+ForwardPbrPipeline.fs,Mibo.MonoGame/Graphics3D/Pipelines/SceneUpload.fs+ForwardPipeline.fs, andMibo.Raylib/Graphics2D/Lighting/LightContext.fsfor 2D.
Integration points
How custom shading gets into the pipeline, per backend:
Escape hatch |
raylib |
MonoGame |
Uniforms you receive |
|---|---|---|---|
|
✓ ( |
✓ ( |
Scene data by name — declare only what you use; absent ones are skipped. Instanced draws are shaded by your shader when it opts in (see Instancing). |
Per-mesh-part effect draw |
— |
✓ |
|
|
✓ |
✓ |
None — the pipeline shader is bypassed; you get a |
.beginEffect(...) / .endEffect() — the inherited uniform contract
Both backends resolve the same uniform names (mirrored SceneUpload
modules). Declare a subset in your shader; the pipeline uploads only what's
present. Absent uniforms are a no-op (-1 location on raylib, null parameter
on MonoGame).
Matrices
Uniform |
Type |
Source |
|---|---|---|
|
|
Per-draw world matrix |
|
|
|
|
|
|
|
|
Active camera world position |
The built-in PBR shaders (and
drawMeshEffect) use a precomposedmvp.beginEffectdoes not setmvp— declarematModel+viewProjand compose the clip-space transform yourself.
Animation clock
Uniform |
Type |
Source |
|---|---|---|
|
|
Total elapsed game time, seconds. Absent on the default PBR shaders; declare it for water/flow effects. |
Material
Uniform |
Type |
Source |
|---|---|---|
|
|
Base color tint |
|
|
Scalar roughness |
|
|
Scalar metallic |
|
|
Emission tint |
|
|
Alpha multiplier |
|
|
UV tiling |
|
|
|
|
|
Albedo map |
|
|
Roughness map (raylib) / Roughness map (MonoGame |
|
|
Normal map |
|
|
Metallic map (raylib) / Metallic map (MonoGame |
|
|
Emission map |
Lights
Uniform |
Type |
Source |
|---|---|---|
|
|
Ambient color |
|
|
Ambient brightness |
|
|
Directional light direction (travel direction) |
|
|
Directional color |
|
|
Directional brightness |
|
|
Active point lights |
|
|
Per-light position (array, default max 8) |
|
|
Per-light color |
|
|
Per-light brightness |
|
|
Per-light radius |
|
|
Per-light falloff exponent |
|
|
Active spot lights |
|
|
Per-light position (array, default max 4) |
|
|
Per-light direction |
|
|
Per-light color |
|
|
Per-light brightness |
|
|
Per-light radius |
|
|
Per-light inner cone cosine |
|
|
Per-light outer cone cosine |
Shadows (opt-in by declaration)
Only uploaded when the frame produced a shadow atlas. A shader that declares none of these renders unshadowed at no cost.
Uniform |
Type |
Source |
|---|---|---|
|
|
|
|
|
Per-caster view-projection (default max 16 casters) |
|
|
Per-caster atlas region (xy=offset, zw=scale) |
|
|
|
|
|
Per-caster receiver-side bias (prevents self-shadow acne; raylib adds an in-shader slope-scale term, MonoGame applies it directly) |
|
|
Per-point-light caster slot, |
|
|
Per-spot-light caster slot, |
|
|
The depth atlas (declared as |
Shadow sampler slot differs by backend. raylib binds the atlas to slot 15 (and sets the
shadowAtlassampler uniform to 15). MonoGame binds it to slot 5 (PointClamp) and exposes it through the effect'sshadowAtlassampler parameter (mgfxc names the sampler after its HLSL declaration, not the register slot — so declaresampler2D shadowAtlas : register(s5), matching the built-inForwardPbr.fx). Both backends use the same uniform name:shadowAtlas.
Skinning (only for skinned draws)
Uniform |
Type |
Source |
|---|---|---|
|
|
Bone palette (uploaded only when bones are supplied) |
Instancing (opt-in)
An .instanced(...) draw inside a .beginEffect(...) scope is shaded by your
shader when it declares the instancing input; otherwise it falls back to the
built-in PBR instanced path. The opt-in convention differs by backend because
each engine feeds per-instance data differently — raylib uses a single vertex
attribute and sets the divisor itself, while MonoGame requires two explicit
vertex streams. The data is the same in both cases: a per-instance 4×4 world
matrix.
matModel is not used for instanced draws (the per-instance transform is
the model matrix); the pipeline uploads identity for it, so a shader that still
declares matModel sees a benign value.
raylib (GLSL #version 330): declare the per-instance attribute.
|
MonoGame (HLSL, SM 3.0/5.0): expose a technique named Instanced whose
vertex shader reads the per-instance matrix as four float4 rows on
TEXCOORD1..4 (usage indices 1-4, to avoid colliding with the mesh's own
TEXCOORD0 on stream 0). This matches ForwardPbr.fx's VS_INPUT_INSTANCED
and the minimal Instanced.fx.
|
Skinned + instanced is not supported. There is no per-instance bone palette; an animated crowd requires a separate scheme (e.g. a texture or buffer of bone matrices indexed per instance). Until such a path exists, keep animated models on non-instanced draws.
drawMeshEffect (MonoGame only)
A fully user-owned Effect. The pipeline sets only the camera + transform
matrices via the effect's IEffectMatrices interface:
Property |
Source |
|---|---|
|
The draw's transform matrix |
|
Active camera view |
|
Active camera projection |
Your effect must implement
IEffectMatrices(asBasicEffect,SkinnedEffect, etc. do). A raw compiledEffectfrom a.mgfxthat doesn't expose the interface gets nothing set — own all parameters yourself and set them before issuing the draw.
raylib has no drawMeshEffect equivalent; use beginEffect (inherits scene
data) or drawImmediate (raw rlgl/raylib calls).
drawImmediate (both backends)
The pipeline shader is bypassed — there is no uniform contract. The callback
receives a SceneContext record with the raw device plus the gathered scene
fields (as F# values, not shader uniforms):
Field |
Type |
Notes |
|---|---|---|
|
|
raylib uses global |
|
camera view matrix |
|
|
camera projection matrix |
|
|
active |
position, target, up, fov, planes |
|
|
ambient + directional + point + spot accumulators |
|
|
|
|
|
Total elapsed game time, seconds |
Set whatever uniforms your own shader needs directly from these values.
2D lit-sprite uniforms
A custom lit-sprite shader must match the built-in uniform layout. Names differ
by backend (raylib camelCase, MonoGame PascalCase) — unlike the 3D
beginEffect contract.
raylib ( |
MonoGame ( |
Type |
Source |
|---|---|---|---|
|
|
|
Ambient color |
|
|
|
Active directional lights (max 4) |
|
|
|
Per-light direction |
|
|
|
Per-light color |
|
|
|
Per-light brightness |
|
|
|
|
|
|
|
Active point lights (max 16) |
|
|
|
Per-light position |
|
|
|
Per-light color |
|
|
|
Per-light brightness |
|
|
|
Per-light radius |
|
|
|
Per-light falloff exponent |
|
|
|
|
|
|
|
Line segment (xy=p1, zw=p2) |
|
|
|
Active occluder segments |
|
|
|
Penumbra softness |
|
|
|
Max raymarch distance |
|
|
|
Normal-map sampler |
— |
|
|
View-projection (MonoGame only) |
The MAX_DIR_LIGHTS (4), MAX_POINT_LIGHTS (16), and MAX_OCCLUDERS (128 on
DX, 32 on OpenGL) constants must match between your shader and the
LightContext2D constructor args.
Worked examples
MonoGame — minimal HLSL for beginEffect
A toon shader that consumes camera + the directional light + material:
|
buffer
.beginCamera(camera)
.beginEffect(toonEffect)
.model(model, transform)
.endEffect()
.endCamera()
.drop()
raylib — minimal GLSL for beginEffect
|
// Fragment shader declares the same uniforms it consumes; load both, then:
buffer
.beginCamera(camera)
.beginEffect(toonShader)
.model(model, transform)
.endEffect()
.endCamera()
.drop()
Convention notes
-
Matrix multiply direction. MonoGame HLSL uses row-vector convention
(
mul(position, matrix)); raylib GLSL uses column-vector (matrix * position). Compose clip space accordingly:mul(mul(position, matModel), viewProj)(HLSL) vsviewProj * matModel * position(GLSL).viewProjis uploaded asview * projectionon both backends. -
Setting raylib uniforms.
[<DisableRuntimeMarshalling>]requiresfixed + NativePtr.toVoidPtrfor scalar/vectorSetShaderValuecalls. See Shaders for the full caveat;SetShaderValueMatrixis exempt. -
Light/shadow budgets. Point-light/spot-light array sizes come from the
pipeline constructor (raylib) or baked
#defines (MonoGame). See 3D Lighting for the limits and how to change them.
See also
-
Shaders — Loading custom shaders, setting parameters, the
DisableRuntimeMarshallingcaveat - 3D Rendering Overview — When to use each escape hatch
- 3D Lighting — Light types, limits, shadow config
- 2D Lighting & Shadows — The 2D lit-sprite pipeline
Mibo