Documentation
    Preparing search index...

    Variable PARTICLE_VERTEX_SHADER_SOURCEConst

    PARTICLE_VERTEX_SHADER_SOURCE: "#version 300 es\nlayout(location = 0) in vec3 corner;\nlayout(location = 1) in vec3 instancePosition;\nlayout(location = 2) in float instanceSize;\nlayout(location = 3) in vec4 instanceColor;\n\nuniform mat4 projection;\nuniform mat4 view;\nuniform mat4 model;\n\nout vec4 vColor;\n\nvoid main() {\n vec4 center = view * model * vec4(instancePosition, 1.0);\n center.xy += corner.xy * instanceSize;\n gl_Position = projection * center;\n vColor = instanceColor;\n}\n" = ...

    The particle vertex stage: a screen-aligned quad, sized in world units.

    centre_view = view · model · vec4(instancePosition, 1)
    corner_view = centre_view.xy + corner.xy · instanceSize
    gl_Position = projection · vec4(corner_view, …)
    

    Offsetting in view space — after the view transform, before the projection — is what makes the quad face the camera without a per-system billboard matrix and without the camera appearing in the render item (§55's billboardMode is deferred for exactly the reason this pipeline sidesteps: a per-view model transform would need a per-view render list). view and projection arrive as separate uniforms rather than the premultiplied viewProjection the other two pipelines take, because the offset has to happen between them.

    instanceSize is the quad's edge length in world units, so a particle of size s spans s units across at any depth under a perspective projection — not a constant number of pixels. The node's own scale does not scale it (the size never passes through model's linear part); that is a documented limitation, and the fix is §36's sizeMode, which the MVP tier does not have.

    Exported so the picking id pass (ParticleIdProgram) shares this stage rather than duplicating the billboard math.