Luxar Viewer API Documentation - v2026.9.22
    Preparing search index...

    Variable GLSL_ELEMENT_ID_SPLITConst

    GLSL_ELEMENT_ID_SPLIT: "\n// Element index split into two 16-bit halves, low in .x and high in .y.\n// The pick pass carries the index through an RGBA32F buffer, and float32\n// has a 24-bit mantissa — so a single float channel cannot represent\n// consecutive indices past 16,777,216, while a node's capacity reaches\n// 2^25 on a 32768-texel device. Both halves are <= 65535, hence exact,\n// and the pick decoder recombines them (see picking-system/pick-render.ts).\n// Kept in INT space: doing the split on a float would already have lost\n// the bit it is meant to preserve.\nvec2 luxarElementIdSplit(uint i) {\n return vec2(float(i & 0xFFFFu), float(i >> 16u));\n}\n" = ...

    The pick buffer's 16-bit element-id split, as a standalone function of an arbitrary index.

    Separate from GLSL_SORTED_INDEX because mesh needs the split WITHOUT the ordering attributes: its pick id is gl_VertexID (mesh IS depth sorted, but its ordering permutes geometry.index itself, so there is no aSortedIndex indirection to read — spec §6.5), so injecting the whole sorted-index block would declare two attributes the geometry does not carry. Declaring an unbound attribute is not merely wasteful on WebGPU — the vertex-buffer layout is cached from the attribute set at first draw.

    The split itself must NOT be written twice. Both halves have to agree with voteWinner's high * 65536 + low recombination exactly (picking-system/pick-render.ts), and a second copy is a place for the shift or the mask to drift where the only symptom is picks resolving to the wrong element past 65,536 — silent, and only on large nodes.