gdgs: Godot Gaussian Splatting
August 25, 2026 · View on GitHub
Maintainer: ReconWorldLab
Current plugin version: 3.3.0
News
- 2026-07-30: Version
3.3.0adds relighting: bake a lighting proxy from the Gaussian data and the scene's lights will shade the splats, darkening everything to a floor so only lit regions brighten. The proxy also makes the splat scene cast real shadows onto ordinary geometry. Read the limitations first — splats store radiance, not material, so baked-in light cannot be removed. See docs/relighting.md. - 2026-07-24: Version
3.2.0-betaintroduces dual rendering backends: alongside the original Compute path, the new Raster ("sticker") backend renders splats through Godot's standard pipeline — bringingMobileandCompatibilityrenderer support, hardware depth-tested occlusion with zero tuning parameters, and materially lower VRAM. This is a beta release: the Raster backend is new and feedback is very welcome. See Rendering Backends and docs/rendering-backends.md. - 2026-07-16: Version
3.1.0adds editor-side collision generation: select aGaussianSplatNodeand generate aStaticBody3Dcollision body directly from the Gaussian data. The pipeline is a GDScript port of the collision approach in PlayCanvas splat-transform. - 2026-04-20: Featured by GameFromScratch in an article.
- 2026-04-20: Covered by GameFromScratch on YouTube.
- 2026-03-31: Merged community contribution PR #6, adding icons, visibility handling, and instancing support.
- 2026-03-27: Published a packaged release on the GitHub Releases page.
- 2026-03-11: Project introduction video published on Bilibili.
0x00 What Is 3DGS
3DGS (3D Gaussian Splatting) is a newer 3D rendering pipeline. Instead of representing a scene with traditional triangle meshes, it uses large sets of 3D Gaussians to reconstruct and render views, which can provide higher quality real-time rendering for captured scenes.
Showcase
These previews show roughly 6 million Gaussian points rendered together inside a real-time game scene.
| Room 0 | Room 1 |
|---|---|
![]() | ![]() |
| Train | Truck |
|---|---|
![]() | ![]() |
0x01 Why This Plugin
3DGS does not follow Godot's native mesh rendering pipeline, and Godot does not currently provide built-in support for importing, rendering, and compositing 3D Gaussian Splatting content.
gdgs fills that gap by providing:
- Import and resource handling for supported 3DGS assets.
- Scene integration through
GaussianSplatNode. - Hybrid rendering with regular Godot 3D content through
CompositorEffect. - Depth-aware composition and occlusion against the scene depth buffer.
- Editor-side collision generation, so splat scenes can interact with Godot physics.
0x02 How To Use
Requirements
- Godot
4.3or newer. - A supported Gaussian asset in one of the formats listed below.
- For the Compute rendering backend (default on desktop): the
Forward Plusrenderer and a GPU/driver with compute shader support. - The Raster rendering backend has no compute requirement and also runs on the
MobileandCompatibilityrenderers (see Rendering Backends).
Rendering Backends
gdgs can render splats two ways, selected once at startup by the
gdgs/rendering/backend project setting:
- Compute (
GSPLAT_RENDERER_COMPUTE) — the original tile-based compute rasterizer. Per-frame GPU projection, a radix sort of(tile | depth)keys, tile-local blending, and composition against scene depth through aCompositorEffect. Per-tile-exact ordering with zero camera lag, at the cost of higher VRAM and aForward Plus-only, compute-only requirement. - Raster (
GSPLAT_RENDERER_RASTER) — a sorted-quad hardware rasterizer ("sticker"). Splat data lives in split data textures (FP32 core + FP16 spherical harmonics), one instanced quad mesh is projected per splat in a spatial shader, and the standard transparent pass blends it with the hardware depth test (no depth-bias params). Much lower VRAM, MSAA/VR/multiview andMobile/Compatibilitysupport for free; the trade-off is a global (not per-tile) back-to-front order — produced by a threaded CPU counting sort — that can lag the camera a frame or two (mild popping).
A deeper comparison — pipeline, data layout, sorting, and colour handling — lives in docs/rendering-backends.md.
Set the backend in Project > Project Settings > gdgs > rendering > backend:
Auto(default) — Compute onForward Pluswith compute support, Raster otherwise.Compute/Raster— force a specific backend.
Selection is startup-only by design: changing the setting takes effect on
the next editor/game restart. If the chosen backend fails to initialize, the
plugin logs a warning and falls back to the other one. The Raster backend draws
through the normal scene, so it does not use the WorldEnvironment
compositor (that step is Compute-only).
Try It Directly
This repository is itself a Godot project: clone it, open the repository root in Godot 4.3+, wait for the first import, and press F5. samples/demo.tscn is the main scene: an interactive relighting sandbox with an orbiting light over the sample asset, a ground plane that catches its shadow, and an ordinary Godot box beside it so the same light can be compared on splats and on real geometry. Every option is a keypress — the on-screen legend lists them.
The demo bakes its own lighting proxy on first run (a few seconds) and caches it, so only the first launch waits. samples/demo.gd builds the whole scene in code, which makes it a worked example of the API.
Installation
- Create an
addonsfolder in your Godot project if it does not already exist. - Copy the
addons/gdgsfolder from this repository into your project asaddons/gdgs. - Open the project in Godot.
- Go to
Project > Project Settings > Plugins. - Enable the
gdgsplugin.
After installation, the plugin root should be available at res://addons/gdgs.
Quick Start
- Add a supported Gaussian asset to your project. The repository includes
samples/assets/demo.sogas a compact sample; larger.plysamples are distributed through the GitHub Releases page to keep clones small. - Wait for Godot to import it into a resource.
- Add a
GaussianSplatNodeto your scene. - Assign the imported resource to the
gaussianproperty ofGaussianSplatNode. - Add a
WorldEnvironmentnode to the scene. - Create a
Compositorresource onWorldEnvironment.compositor. - Add a
CompositorEffectto thatCompositor, and set its script tores://addons/gdgs/runtime/compositor/gaussian_compositor_effect.gd. - Run the scene.
Collision Generation
- Select a
GaussianSplatNodethat has a Gaussian resource assigned. - In the Inspector, find the GDGS Collision block at the top.
- Adjust the parameters if needed (the defaults work for most single objects) and click Generate Collision.
- A
StaticBody3DnamedCollisionBodywith aConcavePolygonShape3Dis added as a child of the node. Generation runs on a background thread with a cancellable progress dialog, commits as a single undo/redo action, and remembers the settings on the node.
Options:
- Mesh:
Faces (greedy)produces few triangles with a blocky silhouette;Smooth (marching cubes)produces a watertight smoothed surface. - Compute:
Autovoxelizes on a private GPU device when available and falls back to CPU; the plugin never touches the rendering pipeline's GPU state. - Scene mode:
Objectfor single objects;Interiorseals a scanned room from the outside;Outdoorfills the ground below the surface.Interiorand Carve (which removes capsule-reachable walkable space) need a childMarker3DnamedCollisionSeed— use Add / Select Seed.Outdoorderives its down direction from the node's current orientation, so orient the node the way it will be used before generating; it also seals the outer rim of the scan where no ground exists. - Export Mesh… exports the collision mesh as
.res,.obj, or.glb.
Physics notes: the generated shape is a hollow triangle-mesh shell with backface_collision enabled. For small, fast-moving rigid bodies, enable continuous_cd on the body (or raise physics_ticks_per_second) to avoid tunneling through thin walls.
The collision module is optional and fault-isolated: if addons/gdgs/collision is missing or fails to load, the plugin logs a warning and rendering is unaffected, so you can delete that folder for a rendering-only installation.
Relighting
- Select a
GaussianSplatNodethat has a Gaussian resource assigned. - In the Inspector, find the GDGS Lighting block, adjust the settings if needed, and click Bake Lighting Proxy.
- Save the result as a
.reswhen prompted — it is then assigned to the node'slightingproperty. - Tick Relight Enabled in the node's Relighting group and add a
Light3Dto the scene.
A splat stores radiance, not material: no normal, no albedo, no occlusion. The bake derives that missing geometry from a lighting proxy — the same voxel field the collision module contours — and gives every splat a surface normal, an ambient-occlusion term and a confidence value. At runtime the colour is scaled by unlit_level + gain × irradiance, so enabling relighting darkens everything and lets only lit regions climb back up. Directional, omni and spot lights all work, they may move at runtime, and both rendering backends implement the same maths.
Relight Cast Shadows is independent and on by default: it mounts the baked proxy as a shadow-only mesh, so the Gaussian scene casts real shadows onto ordinary Godot geometry.
Try it interactively: the bundled demo (samples/demo.tscn, this project's main scene) orbits a light over the sample asset with live toggles for every option.
Read docs/relighting.md before using this. Relighting a capture cannot remove the light that was baked into it, splats do not receive cast shadows, and lighting detail is limited to the proxy's voxel resolution.
0x03 Version History
The current version is 3.3.0. The full per-version history lives in docs/CHANGELOG.md.
Highlights of 3.3.0:
- Relighting: the scene's
Light3Dnodes shade the splats, using surface normals and ambient occlusion baked from a lighting proxy. Up to eight lights, freely movable at runtime, identical on both rendering backends, at +4.7% frame time for one light. - A baked proxy also lets the Gaussian scene cast real shadows onto ordinary Godot geometry.
- Bake artifacts are 4 bytes per splat; the imported Gaussian resource is untouched, so relighting costs nothing when unused.
Highlights of 3.2.0-beta:
- A second, selectable rendering backend — Raster — that draws splats through Godot's standard pipeline, enabling the
MobileandCompatibilityrenderers, MSAA/VR/multiview, and hardware depth-tested occlusion with zero tuning parameters, at materially lower VRAM (FP32 core + FP16 SH data textures). - The
gdgs/rendering/backendproject setting (Auto|Compute|Raster) with startup-time resolution and fault-isolated fallback between backends. - Raster output verified against the Compute backend on matching captures (mean pixel difference ~1.5/255), including per-splat sRGB-to-linear colour handling matching the Compute compositor.
- Beta status: the Raster backend is new; desktop Forward+ is well verified, real mobile hardware coverage is still in progress.
0x04 Features
- Import supported Gaussian assets from
.ply,.compressed.ply,.splat,.sog,glb, and.usdz. - Render through either of two interchangeable backends — tile-based Compute or standard-pipeline Raster — selected by one project setting, with automatic fallback.
- Run on the
MobileandCompatibilityrenderers through the Raster backend. - Convert different source formats into a shared GPU-ready Gaussian resource.
- Center imported Gaussian data by default during resource build.
- Initialize new
GaussianSplatNodeinstances with a default-180degree Z correction when they enter the tree in the default orientation. - Render one or more
GaussianSplatNodeinstances in the same scene. - Composite Gaussian Splat rendering with standard Godot 3D content through
WorldEnvironment.compositor. - Mix Gaussian results against the scene depth buffer.
- Preview in the editor and manipulate the node with a gizmo.
- Built-in debug views for alpha, color, GS depth, scene depth, and depth rejection.
- Generate static collision (
StaticBody3D+ConcavePolygonShape3D) from Gaussian data in the editor, with faces/smooth meshing, CPU/private-GPU voxelization, interior/outdoor scene modes, capsule carve, and mesh export. - Relight splats from the scene's lights using normals and ambient occlusion baked from a lighting proxy, and cast shadows from the splat scene onto ordinary geometry.
0x05 Scene Setup Notes
GaussianSplatNodestores transform and resource references. Actual rendering is performed by the active backend: the Compute backend draws through the compositor pass, while the Raster backend draws through Godot's standard transparent pass.- Multiple
GaussianSplatNodeinstances are supported: Compute renders them together in one Gaussian pass; Raster renders one instanced draw per node. - The
WorldEnvironmentcompositor setup (Quick Start steps 5–7) is only required for the Compute backend; with Raster, adding the node and assigning the resource is enough. - Imported Gaussian data is centered around its average position during resource build, so scenes start closer to the origin by default.
- A newly added
GaussianSplatNodeapplies a one-time default Z correction when it enters the tree with the identity orientation. This keeps duplicated and serialized nodes from receiving the correction twice. - If you replace the source asset contents, reimport it in Godot so the generated resource stays in sync.
0x06 Post Process Parameters
These parameters belong to the Compute backend's compositor effect; the Raster backend has no depth-tuning parameters (occlusion is the hardware depth test).
The compositor effect script is res://addons/gdgs/runtime/compositor/gaussian_compositor_effect.gd.
alpha_cutoff: Pixels with alpha below this threshold are ignored during final composition.depth_bias: Small bias used when comparing GS depth against scene depth.depth_test_min_alpha: Minimum GS alpha required before depth rejection is applied.debug_view: Debug output mode.
debug_view options:
Composite: Final composited result.GS Alpha: Gaussian alpha buffer.GS Color: Gaussian color buffer.GS Depth: Gaussian depth buffer.Scene Depth: Scene depth buffer.Depth Reject Mask: Shows which GS pixels are rejected by depth testing.
0x07 Supported Formats
Standard Gaussian .ply
The importer supports binary little-endian Gaussian Splat .ply files with these properties:
- Position:
x,y,z - DC color coefficients:
f_dc_0,f_dc_1,f_dc_2 - Remaining SH coefficients:
f_rest_0tof_rest_44 - Opacity:
opacity - Scale:
scale_0,scale_1,scale_2 - Rotation:
rot_0,rot_1,rot_2,rot_3
.compressed.ply
- Supported through the dedicated compressed PLY decoder.
- Detected automatically from the
.compressed.plysuffix or packed vertex properties.
Legacy .splat
- Supported for older Gaussian Splat record-based assets.
.sog
- Supports SOG version
2archives.
This importer is meant for Gaussian Splatting style assets, not generic point cloud files.
.glb
- Supports uncompressed glTF files using the
KHR_gaussian_splattingextension.
.usdz
- Supports NuRec-style USDZ archives (Scaniverse / NVIDIA Omniverse exports): a ZIP holding a USD scene graph plus a gzip-compressed MessagePack
.nurecpayload with float16 Gaussian tensors.
0x08 Repository Layout
addons/gdgs: Plugin root in this repository.addons/gdgs/importers: Import plugins, parsers, decoders, and resource builders.addons/gdgs/runtime: Runtime nodes, resources, the backend seam (render/backend), the Compute backend (render/compute+compositor+debug), and the Raster backend (render/raster).addons/gdgs/editor: Editor-only integrations such as gizmos.addons/gdgs/collision: Optional editor-side collision generation (inspector UI, worker pipeline, voxelizer shader).addons/gdgs/lighting: Optional editor-side lighting-proxy bake (inspector UI, worker bake pipeline). Bake-time only — shipped games relight from the baked resource without it.docs: All non-README documentation — Chinese README, changelog, contributing guide, architecture notes, and the rendering-backend comparison.samples: The demo scene (demo.tscn+demo.gd), sample Gaussian assets, and media.tests: Headless tests used by CI (smoke, collision pipeline, Raster sorter/data-texture, backend selector, lighting bake and light rig), plus the visual A/B harness and its minimal reference scene.project.godot: Development project for working on the plugin itself; excluded from Asset Library exports.
Only addons/ ships to users; everything else is development and documentation support.
0x09 Known Limitations
- The Raster backend is new in
3.2.0-beta: it is verified against the Compute backend on desktopForward PlusandCompatibility(matching-pose captures differ by ~1.5/255 on average), but coverage on real mobile hardware is still in progress. Please report what you see. - The Compute backend targets desktop
Forward Plusonly and depends on Godot's compositor and compute pipeline, so it does not run on theMobileorCompatibilityrenderers. Use the Raster backend there (see Rendering Backends). - The Raster backend uses a global (not per-tile-exact) back-to-front order that can lag the camera a frame or two, so fast rotations may show mild popping.
- On 4K displays, rendering errors or visual glitches may occur when GPU memory pressure becomes too high. Reducing the Godot viewport resolution may help. Reported in issue #3.
- Relighting modulates baked radiance, so it cannot remove light that was captured into the asset, and splats cast shadows through the proxy but do not receive them. Full list in docs/relighting.md.
- The render manager currently lives as a shared root-level runtime manager, so very complex editor multi-scene or multi-viewport workflows may still need additional validation.
- Standard
.plysupport expects binary little-endian Gaussian Splat data, not arbitrary point cloud layouts. .sogsupport currently targets version2archives only.
0x0A Acknowledgements
- The collision generation pipeline is a GDScript port of the voxelization and collision approach in PlayCanvas splat-transform, published by PlayCanvas Ltd. under the MIT License. Many thanks to the PlayCanvas team for openly sharing that work.
- The shader work in this plugin was developed with reference to 2Retr0/GodotGaussianSplatting. Thanks to 2Retr0 for publishing that project.
- Thanks to @4321ba for PR #6, which contributed editor icons, visibility handling improvements, and instancing support for shared Gaussian data.
- The upstream
2Retr0/GodotGaussianSplattingrepository is published under the MIT License. If you reuse or redistribute closely related derivative work, review and retain the relevant upstream license notice. - The radix sort shader files also retain their own upstream attribution headers, as documented in the shader sources.
0x0B References
- 2Retr0/GodotGaussianSplatting
- PlayCanvas splat-transform
- 3D Gaussian Splatting for Real-Time Radiance Field Rendering
0x0C Contributing
Issues and pull requests are welcome, in English or Chinese. See docs/CONTRIBUTING.md for the development setup (the repository opens directly as a Godot project), style notes, and the CI checks that run on every PR.
0x0D License
This project is released under the MIT License. A copy of the license is bundled inside addons/gdgs, so it travels with the plugin wherever the folder is copied or downloaded.



