Builds the record, assigning through the accessors so one copy of each
rule covers the option and every later write alike (the F14 discipline
Material's constructor follows).
What to store when the stencil test passes and the depth test fails;
"keep" by default.
The one worth stating: a mask pass usually runs with depthTest: false or
depthWrite: false, because a mask that is occluded by the geometry it is
masking would punch a hole in itself.
The comparison, "always" by default — see StencilFunc for the
argument order (ref OP stored).
The bits of the reference and the stored value the test looks at;
0xff (all eight) by default.
This is the bit-plane selector nested clipping needs: a clip that owns bit 2
tests with readMask: 0b100 and is blind to every other level's bits.
The reference value the test compares and "replace" writes; 0 by default,
an integer in 0…MAX_STENCIL_VALUE.
The bits a stencil write may change; 0xff by default, and 0 for the
common "test but never write" material.
A write mask of 0 makes StencilState.failOp,
StencilState.depthFailOp, and StencilState.passOp inert —
which is a legitimate way to say "read-only", and cheaper than setting all
three to "keep", because it also protects against a later edit that
changes one of them.
An independent copy. Materials share a StencilState by reference — like
every other resource in §83's model — so this is how a caller derives a
second pass from a first without editing the first.
§57's
stencilmember: the stencil test a material's draws run under, and what they write back (§67).A material that declares no
stencilleaves the stencil test disabled, which is GL's initial state and the state every frame this engine drew before this class existed ran in. That is the byte-identity guarantee, and it is the property that let this land under the pixel-golden gate.The defaults are GL's initial state, deliberately
new StencilState()isalways/ref 0/0xff/0xff/keep/keep/keep— a stencil test that is enabled and passes everything, changing no stored value. It is a no-op with a cost, and that is the point: the only thing a bareStencilStatechanges is thatenable(STENCIL_TEST)is issued, so a material that opts in and then names nothing gets the same picture, and every field it does name is the only thing that moved.Validated on assignment, like
opacityandblendMode(F14)Every property below is an accessor applying the same rule the constructor applies. The backend maps these names through a fixed table and passes the numbers to
stencilFunc,stencilOp, andstencilMask; §61 forbids throwing inside a frame, so the assignment is where a bad value has to fail. A rejected write leaves the previous value in place.Mutating a
StencilStatedoes not announce anything to a material's version counter, for the reason §57's other render state does not: a backend reads render state per draw and caches none of it.