Skip to content

Voxel rendering for Godot 4.3 (GPU, shader, DDA algorithm)

License

Notifications You must be signed in to change notification settings

viktor-ferenczi/godot-voxel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Voxel

Voxel rendering addon for Godot 4.3.

Based on an efficient 2-level DDA algorithm, implemented 100% on the GPU as a fragment shader.

This approach allows for good performance and opens up the possibility of making runtime changes to voxels at a relatively low cost.

Detailed documentation in mostly in the shader source files.

Scroll down on this page for screenshots on what's possible.

Example

Open the example scenes:

  • Examples\Park
  • Examples\TorusBox

Example Park scene

Example TorusBox scene

There are separate shaders for the opaque, transparent and shadow passes. They are rendered by their own child nodes, the shaders are defined there. GDScript is required only to verify the configuration and set up the child nodes in a consistent way.

Algorithm

The shader is based on a 2-level DDA algorithm, this is also known as raymarching.

From the perspective of the volume the voxels are rendered into is just the simplest possible box mesh. It does not have anything else other than 8 vertices and 12 faces. It does not need UV, nor normals.

Front faces are culled, only the back faces are rendered. It allows for viewing the voxel volume from inside, while still provide full view from the outside.

For each view ray the shader

  • map the ray to the voxel box (model space)
  • calculate front face intersection from the back one
  • walks over the voxel cubes (1st level)
  • skip any voxel cubes behind the view plane
  • for each voxel cube with any non-empty voxels
    • skip any voxels behind the view plane
    • call the sampler to determine whether the voxel exists, opaque or transparent
    • accumulate transparent voxels along the ray
    • stop at the first opaque voxel along the ray
  • call the sampler to fetch PBR properties (separate for opaque and transparent)

The opaque, transparent and shadow passes differ, because they do only the processing required for the given pass. Transparent voxels are not rendered to the shadow map, for example.

The DDA algorithm in the shader code is designed to be reusable. It is easy to provide a custom sampler for your specific needs without touching the raymarching algorithm. This way you can change the PBR material of your voxels in any way you want and look up extra information based on the voxel type or position to match your game design goals. What is considered to be opaque voxel can also be customized.

Remarks

Vox import

There was a Vox resource loader, but it got broken by a late Godot beta.

Texture array imports

The texture array import configuration is critical for the shader to accept the textures. If you get rendering errors in the Output tab, then that's the most likely reason.

Transparency

Transparency is not tested with this current project, but worked well before. I will include a test project for transparency later.

The shader implements color filtering with proper transmittance calculation. It is taking the screen texture as the background, which poses some limitations. Color filtering works as expected inside the same voxel volume, but falls back to alpha channel by turning the transparency effectively grayscale.

Plans

  • Resurrect the Vox resource loader
  • Clean up and add the automated placement of
    • Lights to make use of SDFGI
    • Occluders to reduce overdraw
    • Colliders to enable physics
  • Add a one bit per voxel texture to speed up skipping empty voxels.
  • Add more examples (PRs are very welcome, I'm not an artist)

Screenshots

Screenshots and videos what this plugin may be able to do later, once I can clean up and add all the GDExtension based C code back to the project which I had to remove.

Voxel asserts used in the tests: Tiny Voxel Dungeon by maxparata

Vox import

Godot (SDFGI, SSAO, Glow) vs. MagicaVoxel rendering: Full resolution Godot vs. MagicaVoxel

Light placement

Automated placement of light in the cluster centroids of emissive voxels: Light Placement

Lighting test: Lighting

Staircase lights: Staircase Lights

Occluders

I made no screenshots of occluder placement, but they work similarly to collider placement.

Colliders, physics

Collider placement

Collision Boxes

Collision Shapes

Videos are on OneDrive, because they are big.

Transparent voxels

Transparency Nature

Transparency Venice

It actually calculates color transmittance, so colorful glass behaves as expected. Unfortunately there are no colorful shadows. They could be faked with projectors, which should be supported (not tested it yet).

Rendering performance tests

60fps with 64 rooms (geForce RTX 3080Ti) Perf. test: 64 rooms

With automated light placement included (no fps recorded, unfortunately, it was around 30-40): Perf. test: Lighting, 64 rooms

Fun bugs

A bug resulted in a fancy memory garbage visualizer during shader development:

Bug: Fancy Memory Garbage Visualizer

About

Voxel rendering for Godot 4.3 (GPU, shader, DDA algorithm)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published