AdvancedOptionalbindingsBindings the model needs, such as its own material fields
OptionalheaderCode for the {{header}} slot, such as helper functions and constants
Optionalgl?: stringGLSL source (WebGL)
Optionalgpu?: stringWGSL source (WebGPU)
The bit's ShaderBit#name, which must be unique
The shading math for one light, run inside the loop; CreateLightingBitOptions lists what it reads
Optionalgl?: stringGLSL source (WebGL)
Optionalgpu?: stringWGSL source (WebGPU)
OptionalpostCode that runs once, after the light loop
It writes the template's finalColor, as in
finalColor = ambient * occlusion + directLight + emissive;.
Optionalgl?: stringGLSL source (WebGL)
Optionalgpu?: stringWGSL source (WebGPU)
OptionalpreCode that runs once, before the light loop
Declare the accumulators here, and anything that doesn't depend on the light. What it declares
stays in scope for perLight and postLighting.
Optionalgl?: stringGLSL source (WebGL)
Optionalgpu?: stringWGSL source (WebGPU)
OptionalrequiresBits the model needs in the shader, such as mathConstantsBit for PI and INV_PI
OptionalstructsStructs the model declares
OptionaltexturesTextures the model samples, such as a lookup table
Options for createLightingBit: the shading math of a lighting model, such as toon or Blinn-Phong, around a light loop the factory writes
The generated fragment
lightingslot runs:preLighting, declare and zero your accumulators, such asdirectLight, and work out anything that doesn't depend on the light, such asnDotV.perLight, add this light's share to them.continue;skips the rest of this light. Lights that don't reach the fragment or that the surface faces away from never get here.postLighting, writefinalColorfrom the accumulators and whatever the material bit declared, such asemissive. Exposure, fog and tone mapping run after it.The loop sits in a block of its own, so names these snippets declare aren't visible to later slots such as
end.What
perLightcan readlightLightlightDirvec3attenuationf32nDotLf32max(dot(normal, lightDir), 0), above 0shadowf32normalvec3viewDirvec3Anything else the model needs, such as
albedoandroughness, comes from the material bit that runs before it. The light's kind islight.kindin WGSL andlight.typein GLSL; compare it withLIGHT_DIRECTIONAL,LIGHT_POINTorLIGHT_SPOT.Lobes
Another bit in the descriptor can add per-light math to this loop, rather than run a second loop that samples every shadow again, through the fragment slots
lobePreLighting,lobePerLightandlobePostLighting. Each runs after the matching snippet here, in the order the lobe bits are listed, solobePostLightingsees the assembledfinalColorand can rewrite it.Requirements
Use the bit in a material with BaseMaterial3D#lit on, the default. A pass's own shader can't run it.