Ogc3dTilesGaussianProgram

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.sphericalHarmonics for 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.

Constructors

Link copied to clipboard
constructor()

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard

Indicates the approximate size of the OpenGL resources referenced by this GPU program.

Functions

Link copied to clipboard

Focal length in pixels = viewportHeight / (2 * tan(fov / 2)). The vertex shader uses this to convert metric splat scale to projected gl_PointSize.

Link copied to clipboard
fun loadMinAlpha(value: Float)

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.

Link copied to clipboard
fun loadModelview(matrix: Matrix4)

Tile-local → eye-space (modelview * tileToWorld).

Link copied to clipboard
fun loadPickColor(color: Color)

Unique pick-ID RGBA emitted on the splat core when loadPickMode is true.

Link copied to clipboard
fun loadPickMode(value: Boolean)

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.

Link copied to clipboard
fun loadPositionDequant(centerX: Float, centerY: Float, centerZ: Float, halfRangeX: Float, halfRangeY: Float, halfRangeZ: Float)

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.

Link copied to clipboard
fun loadProjection(matrix: Matrix4)

Eye-space → clip-space.

Link copied to clipboard

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).

Link copied to clipboard
open override fun release(dc: DrawContext)

Frees any resources associated with this instance. After this method returns the rendering resource is invalid, and any associated GL object is deleted.

Link copied to clipboard