Skip to content

Document impact of -C chunk size on LOD coverage in sparse scene regions #187

@mapvis-git

Description

@mapvis-git
Image Image Image

The -C parameter (max Gaussians per chunk) has an important undocumented side effect: in scenes with varying
Gaussian density, a high -C value produces very few large chunks. Sparse regions of the scene may end up with
only 1 chunk across all LOD levels — or none at all for higher LOD levels.

Observed behavior

Same outdoor terrain scene (~210 × 215m, 5 LOD levels), processed two ways:

Problematic (-C 1024 -X 64): 3 chunks total (1 per LOD level) → visual artifacts in sparse regions

Working (-C 64 -X 32): 31 chunks → full spatial coverage, no artifacts

Commands

Problematic:

node --max-old-space-size=32000 $(which splat-transform) \
  -C 1024 -X 64 \
  LOD0.ply -l 0 LOD1.ply -l 1 LOD2.ply -l 2 \
  output/lod-meta.json --filter-nan --filter-harmonics 3

Working:

node --max-old-space-size=28000 $(which splat-transform) \
  -C 64 -X 32 \
  LOD0.ply -l 0 LOD1.ply -l 1 LOD2.ply -l 2 LOD3.ply -l 3 LOD4.ply -l 4 \
  output/lod-meta.json --filter-nan --filter-harmonics 0

Reproduction attempt

We reverted to the exact git commit containing the original configuration using git worktree and tested all
available dataset variants (3 to 31 chunks) with all original parameter combinations active. Despite this, we were
unable to reliably reproduce the artifacts in isolation. The issue appeared during development but seems to
depend on a specific combination of camera position, LOD parameters, and data distribution.

Suggestions

  • Document that -C should be chosen relative to the Gaussian density of the sparsest regions, not the
    average
  • For outdoor terrain with varying density, -C 64 is significantly safer than -C 256 or higher
  • A warning when LOD 1+ has significantly fewer chunks than LOD 0 would help catch this early

splat-transform version: 1.9.2

Und Issue 1 ebenso:

Title: lodBehindPenalty and lodUpdateAngle defaults cause visual artifacts in orbital/terrain viewers


When using GSplat LOD streaming with an orbital camera (terrain viewers, landscape visualization), the default
values for lodBehindPenalty (5) and lodUpdateAngle (90°) cause black holes / missing regions in the rendered
scene.

Root cause

These defaults are designed for first-person cameras. For orbital cameras covering 360° of terrain, parts of the
scene are constantly outside the forward view cone:

  • lodUpdateAngle: 90 → only chunks within a 90° cone are updated correctly
  • lodBehindPenalty: 5 → chunks outside the cone get 5× their actual distance as effective LOD distance
  • Result: terrain chunks slightly behind the camera receive an inflated effective distance → wrong LOD level
    requested → black holes in sparse regions

Fix

app.scene.gsplat.lodUpdateAngle   = 180; // full sphere, no penalty cone
app.scene.gsplat.lodBehindPenalty = 1;   // no distance penalty

Additional context

lodBaseDistance measures camera→chunk distance, not orbit zoom distance. For a ~200m outdoor scene, terrain
chunks can be 300–400m from the camera even at moderate zoom. This is also undocumented and caused us to initially
set values far too small (e.g. base: 8), pushing distant chunks into LOD levels with no data.

Reproduction attempt

We reverted to the exact git commit containing the original configuration (lodUpdateAngle: 90,
lodBehindPenalty: 5, lodBaseDistance base: 8, minZoom: 3) using git worktree. Despite testing all dataset
variants and parameter combinations, we could not reproduce the artifacts consistently. Setting the values above
resolved the issue completely.

Suggestion

Consider documenting recommended values for orbital/terrain use cases, or providing a preset:

app.scene.gsplat.setCameraMode('orbital'); // hypothetical API

PlayCanvas version: 2.17.1 (self-hosted)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions