Drawable Tile Points
Color-pass drawable for one 3D Tiles point cloud tile. Holds a reference to the pre-uploaded PointCloudContent, the tile-to-world transform, and per-frame state for the shadow + sightline receiver paths. Pool-recycled.
Casts cascade shadows as 1-pixel point splats: the depth-only caster program is triangle-oriented but happily rasterises GL_POINTS, with gl_PointSize defaulting to 1. Softened by the receiver's PCF, dense LiDAR clouds produce believable ground-halo shadows; sparse clouds look slightly stippled. A follow-up may add a dedicated points depth program that writes a size-attenuated gl_PointSize matching the colour pass's per-splat disc.
Properties
Per-tile base point size in pixels at 1 m eye depth. Caller sets at enqueue time.
Focal length in pixels = viewportHeight / (2 * tan(fov / 2)). Caller sets at enqueue time from rc.viewport.height + rc.camera.fieldOfView.
Set from Tile3d.isFallback at enqueue. Fallback tiles render only where stencil != stencilId so they fill gaps without overlaying finer descendants.
Tile kept alive only as a shadow caster (outside the view frustum): rasterizes in the cascade depth pass but skips the color pass entirely.
Per-cascade cull test reads these. Suppressed (returns null) when the layer disabled casting via ShadowMode.castsShadows = false so the depth pass doesn't even iterate.
World-space bounding sphere radius. Only consulted when shadowCasterCenter is non-null.
Interleaved VBO resolved fresh from the RR cache at enqueue time. Matches the drawable-enqueue resolution pattern used by DrawableTileMesh / Path / Polygon / OSM Buildings — keeping the ref on the drawable instead of on PointCloudContent means a cache eviction between frames surfaces as a null slot here (skipping the draw) rather than a stale BufferObject.id bind on a content-cached ref.
Functions
Cascade depth-pass dispatch. Binds the same VBO as the colour pass, points attribute 0 at the interleaved position field, and rasterises GL_POINTS into the cascade depth texture — each occluder is one pixel rather than a filled triangle; the receiver's PCF smears those impulses into soft splats on the ground.