Skip to content

RFC: Add native SPZ / Gaussian Splat renderable support #342

Description

@xiaokhkh

Summary

I would like to propose first-class native SPZ / Gaussian Splat rendering support for React Native Filament.

The goal is to load .spz files as native Filament renderables instead of pushing large raw splat buffers through JS. I have a working prototype inspired by SparkJS-style Gaussian splat projection/material behavior, adapted to RNF + Filament.

Proposed direction

Native path:

SPZ buffer
  -> native decoder
  -> splat attributes
  -> quad vertex/index buffers
  -> custom Filament material
  -> Filament renderable entity
  -> RNF hook/component

Public API shape could be:

const splat = useGaussianSplat(source, {
  addToScene: true,
  maxSplats,
  splatScale,
  renderOptions,
})

<GaussianSplat source={source} renderOptions={renderOptions} />

A lower-level engine.loadSpz(...) API can return a native GaussianSplatAsset exposing the entity, bounds, point counts, render-size update, camera-view update, and view sorting.

Performance plan

For larger SPZ files, optimization should preserve visual behavior:

  • build spatial chunks and chunk AABBs at load time
  • cull chunks before per-splat sorting
  • gather visible splats into one candidate list
  • still update one globally sorted index buffer for transparent blending correctness
  • reuse index upload buffers to reduce allocation pressure
  • expose diagnostics for total points, rendered points, visible candidates, and sort/update timing

Non-goals

  • not SPZ-to-GLB conversion
  • not 3D Gaussian training/reconstruction
  • not app-specific collision/FPS/navigation logic
  • not a public dependency on SparkJS internals
  • not one large PR mixing core renderer, demos, docs, and optimization

Suggested PR split

  1. Native SPZ decoder and GaussianSplat resource/wrapper foundation.
  2. Filament material asset and renderable construction.
  3. TypeScript types, useGaussianSplat(), and <GaussianSplat />.
  4. Camera/render-size sync and sorting integration.
  5. Example scene and docs.
  6. Performance follow-up: chunk AABB culling, global sorted index buffer update, and diagnostics.

If this direction sounds reasonable, I can start with a small foundation PR and keep app-specific logic out of RNF core.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions