Skip to main content
Marble SPZ files are exported in the generated asset coordinate frame. When you render them outside Marble, use assets.splats.semantics_metadata to convert Gaussian centers and Gaussian sizes into metric, ground-aligned coordinates.

Read the scale metadata

Completed world responses include SPZ URLs and scale metadata together:
{
  "assets": {
    "splats": {
      "spz_urls": {
        "500k": "<500k_spz_url>",
        "100k": "<100k_spz_url>",
        "full_res": "<full_res_spz_url>"
      },
      "semantics_metadata": {
        "metric_scale_factor": 1.23,
        "ground_plane_offset": 0.42
      }
    }
  }
}
The numeric values in this example are representative, not fixed constants. Use the values returned with the world you are rendering. metric_scale_factor converts raw generated asset units to meters. ground_plane_offset places the metric ground plane at y = 0.

Apply center and size scale

Apply scale to Gaussian centers and Gaussian sizes:
def to_metric_gaussian(center, linear_scale, semantics):
    scale = semantics["metric_scale_factor"]
    metric_center = center * scale
    metric_center[..., 1] -= semantics["ground_plane_offset"]

    metric_linear_scale = linear_scale * scale
    return metric_center, metric_linear_scale
The ground-plane offset applies only to Gaussian centers. Do not apply ground_plane_offset to Gaussian sizes.

Handle log-scale fields

Some Gaussian splat formats expose scale_0, scale_1, and scale_2 as log-space values. If your decoder gives you log scales, add the logarithm of the metric scale instead of multiplying the log values directly:
import math


def to_metric_log_scale(log_scale, semantics):
    return log_scale + math.log(semantics["metric_scale_factor"])
Equivalently, convert to linear scale first:
import numpy as np


linear_scale = np.exp(log_scale)
metric_linear_scale = linear_scale * semantics["metric_scale_factor"]
metric_log_scale = np.log(metric_linear_scale)
Multiplying scale_0, scale_1, and scale_2 directly is only correct if your decoder exposes those fields as linear sizes.

Convert renderer axes separately

semantics_metadata converts raw Marble SPZ coordinates to a metric, ground-aligned frame. It does not include renderer-specific axis conversion. Generated Marble SPZ assets use the marble_raw_opencv convention. If your engine uses an OpenGL or Three.js-style frame, apply your engine’s axis conversion after applying metric scale and ground alignment. Marble’s web viewer applies a 180 degree rotation around the X axis for generated SPZ assets.