Ogc3d Tiles Gaussian Program
Colour-pass shader for 3D Tiles Gaussian-splat content. Renders one GL_POINTS per splat with an anisotropic, screen-space-projected covariance footprint and a Gaussian falloff in the fragment — the standard 3DGS "EWA splat" rasterizer pipeline.
Per-splat math: the rotation quaternion + 3-axis scale define a tile-local 3D Gaussian with covariance Σ_local = R · diag(s)² · Rᵀ. The vertex shader transforms R through the modelview's 3×3 (giving eye-space covariance Σ_eye = T·Tᵀ, T = W·R·diag(s)), then projects through the perspective Jacobian J = [[f/z, 0, -f·x/z²], [0, f/z, -f·y/z²]] to a screen-space 2×2 covariance Σ_2d = J · Σ_eye · Jᵀ. The standard 3DGS +0.3 px low-pass anti-alias term is added to the diagonal. The point radius is alpha-aware — r = σ·√(2·ln(α/minAlpha)), ~3σ for opaque splats, shrinking for faint ones — so fragments the discard threshold would kill are never rasterized. The inverted 2D conic, pre-scaled by the post-clamp gl_PointSize squared (driver-bounded by GL_ALIASED_POINT_SIZE_RANGE), is passed as a mediump varying; the fragment stage runs fully in fp16 and uses exp(-½·dᵀ·Σ⁻¹·d) on gl_PointCoord offsets directly.
Deliberate scope limits:
Per-splat solid colour: reads RGBA straight from the codec output; no SH evaluation. The codec preserves higher-band SH coefficients on
earth.worldwind.layer.ogc3d.content.GaussianContent.sphericalHarmonicsfor a view-dependent path on top of this one.No shadow / sightline receivers: a typical Gaussian scene is self-shadowed; routing the GL_POINTS path through cascade receivers adds noise without much fidelity gain.
Caller must enable premultiplied-alpha blending (GL_ONE, GL_ONE_MINUS_SRC_ALPHA) before draw — the fragment shader emits (rgb * a * falloff, a * falloff) so back-to-front sorted splats accumulate correctly without over-darkening overlaps.
Properties
Functions
Focal length in pixels = viewportHeight / (2 * tan(fov / 2)). The vertex shader uses this to convert metric splat scale to projected gl_PointSize.
Fragments whose Gaussian-weighted alpha falls below this threshold are discarded — a fillrate optimisation that skips negligible contributions instead of drawing them. Defaults to 0.01.
Tile-local → eye-space (modelview * tileToWorld).
Unique pick-ID RGBA emitted on the splat core when loadPickMode is true.
When true, the fragment discards the Gaussian fringe (α<0.5) so depth writes only on the splat core. Pick depth-readback then unprojects to the splat surface (e.g. a building roof) instead of the terrain behind it.
Per-tile position dequant. Vertex shader computes modelPos = vertexPosition * halfRange + center, where vertexPosition is the GPU- normalized signed int16 in -1, +1. center = (min+max)/2, halfRange = (max-min)/2 along each axis of the tile's bounding box.
Eye-space → clip-space.
Global multiplier applied on top of the per-splat projected size. Defaults to 1.0; callers tune up/down to control oversplatting density (higher = fluffier blend, lower = crisper edges with visible point gaps).
Frees any resources associated with this instance. After this method returns the rendering resource is invalid, and any associated GL object is deleted.