Mesh visual shader pair (GLSL3) — the hand-written reference twin of
shader-tsl.ts.
Mesh is the first geometry type in Luxar that shades. The other three are
purely emissive per-element sprites: their fragment stage computes a soft falloff
and emits colour, with no notion of a surface orientation. A triangle has one, and
a mesh drawn flat is an unreadable silhouette — so this pair adds a light-free
shade term, and with it the two hazards that come from reading a normal:
degenerate/corrupt stored normals, and back faces.
It is also the first pair whose per-vertex data arrives in vertex attributes
rather than an RGBA32F element texture, so there is no texelFetch prologue, no
aSortedIndex indirection, and no quad expansion — position and normal are
three's own auto-declared attributes and the draw is an ordinary indexed
drawElements.
Shader variants (spec §6.2 / §6.4)
Define
Effect
USE_COLORMAP
read aScalar + LUT instead of the color attribute
LUXAR_GAMMA_ONE
skip the gamma pow() (pow(x, 1) == x)
LUXAR_NO_GOG
skip the intensity/offset mul-add-clamp chain
LUXAR_MESH_FLAT_NORMAL
derivative-only normal; the normal attribute and its varying are not read at all
LUXAR_MESH_ALPHA_CUTOUT
opaque mode: hard, order-independent alpha cutout
LUXAR_MAX_RGB_CONTRIBUTION
max mode: premultiply RGB by coverage
The stored-normal-vs-flat choice is a compile-time variant, not a runtime
branch, because a declared-but-unbound normal attribute reads (0, 0, 0, 1)
rather than "absent" — there is no runtime value that means "no normals". It is
decided once per node in createMeshNode and handed to both backends, so the two
can never derive it differently (spec §6.2).
Mesh visual shader pair (GLSL3) — the hand-written reference twin of
shader-tsl.ts.Mesh is the first geometry type in Luxar that shades. The other three are purely emissive per-element sprites: their fragment stage computes a soft falloff and emits colour, with no notion of a surface orientation. A triangle has one, and a mesh drawn flat is an unreadable silhouette — so this pair adds a light-free shade term, and with it the two hazards that come from reading a normal: degenerate/corrupt stored normals, and back faces.
It is also the first pair whose per-vertex data arrives in vertex attributes rather than an RGBA32F element texture, so there is no
texelFetchprologue, noaSortedIndexindirection, and no quad expansion —positionandnormalare three's own auto-declared attributes and the draw is an ordinary indexeddrawElements.Shader variants (spec §6.2 / §6.4)
USE_COLORMAPaScalar+ LUT instead of thecolorattributeLUXAR_GAMMA_ONEpow()(pow(x, 1) == x)LUXAR_NO_GOGintensity/offsetmul-add-clamp chainLUXAR_MESH_FLAT_NORMALnormalattribute and its varying are not read at allLUXAR_MESH_ALPHA_CUTOUTopaquemode: hard, order-independent alpha cutoutLUXAR_MAX_RGB_CONTRIBUTIONmaxmode: premultiply RGB by coverageThe stored-normal-vs-flat choice is a compile-time variant, not a runtime branch, because a declared-but-unbound
normalattribute reads(0, 0, 0, 1)rather than "absent" — there is no runtime value that means "no normals". It is decided once per node increateMeshNodeand handed to both backends, so the two can never derive it differently (spec §6.2).