Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Yes, I am using ray marching for voxel rendering.  My engine also supports rendering lines and triangles (meshes) via rasterization.

I'll have to write up an outline of how I'm doing the ray marching.  It's going to be a quite long outline...  I'll have to get back to you on this.

Thanks!

Any updates? (on raymarching)

I'm still struggling with trying to put the GLSL code into an outline description that makes sense (isn't too abstract).

Don't worry about it being to abstract. I know a little GLSL and a little raymarching. and a little bit about octrees.

Here's the algorithm I'm using:
Pastebin -- Tetrahexacontree Voxel Volume Raymarching

Thanks, I'm still reading through it, its complicated and a little confusing.

Are you using sdf raymarching?

No SDF used.  I'm using bounding box intersection tests to move ray forward.

(1 edit)

P.S.  I'm using slab method ray box intersection.  It's more or less the same code (GLSL + 3D) as this Scratchpixel - A Minimal Ray-Tracer.  I'm also having to use dynamic epsilon values to slightly enlarge bounding boxes for intersection to make it work correctly for nearest side and farthest side ray bounding box intersections to get correct "t" values inside or outside of bounding box.  Additionally, sometimes the bounding box intersections fail, so the code has to handle that gracefully or GLSL shader threads will get stuck in infinite loops.

What is a "tree root node index" in the pastebin?

(3 edits)

Tree nodes (including the root node) are stored in an array of nodes.  "tree root node index" is an integer variable containing the index of the root node in said array.  Many array index based tree implementations have the root at the first element in the array (index zero), but in my implementation the root node can be any node in the array of nodes.

The reason I've implemented things this way is so that if the tree's bounds need to be expanded (voxel volume(s) need to be added to the tree outside of tree's current bounds [in C++ code]), the tree doesn't need to be rebuilt, but instead tree's bounds are expanded accordingly and a free/unused node in the array of nodes (which is a dynamic size data structure like a C++ std::vector of tree nodes) becomes the new root node and the old root node becomes one of new root node's children.

P.S. Disregard the part I set as strike though text in the previous  reply.  That was left over code from the octree version and I had to re-implement tree bounds size increase by rebuilding the tetrahexacontree due to integer coordinate powers of two alignment restrictions if the old root was made a child of a new root.  So "tree root node index" is zero (always first element of array of nodes) and "tree root node index" is no longer passed to the tetrahexacontree voxel volumes raymarching shader via a uniform buffer object field (just hard coded now).

I finally got my own voxel engine started :D thanks for your help so far, one day maybe it will be as good as yours.image.png

You're welcome.  Keep up the hard work!  I say "hard work" because it has been a struggle to get my voxel engine to where it is at now.  I'm still struggling with the compute shader stuff in between working on others parts of the code.

I got mipmaps generating via a compute shader but mipmap regeneration for voxel volume updates (adding or removing voxels) still has a bug.

If you haven't done so already, check out Douglas Dwyer's videos about his voxel engine which is farther along than my voxel engine:  https://www.youtube.com/@DouglasDwyer/videos

Yes Douglas's videos are very impressive. mipmaps? I haven't heard much about those. care to tell me more?

Wikipedia on Mipmap: https://en.wikipedia.org/wiki/Mipmap

I'm using 3D mipmaps of voxel volumes to improve performance and visual quality of volumes that are farther away as part of the level of detail system in my voxel engine.

This video shows them (color coded for testing) in action:

Wow, so its like LOD for raytracing/raymarching?

(4 edits)

Exactly!

Stating the obvious:  The default graphics settings in game should be set so the LOD isn't noticeable, but one can set LOD to be very aggressive for better performance at the cost of visual quality. 

To calculate the LOD level during raymarching, I use the equation logN(t/d) where N is the logarithm of base N (2, 4, 8, up to 128), t is the ray's distances from the camera and d is a divisor (1, 2, 4, up to 32768).  d controls how close to the camera the first LOD level is active and N controls the (logarithmic) world distance between LOD levels.

This video shows how the graphics looks (both with and w/o color coding) while adjusting the LOD equation's d parameter (via hot keys).  See yellow text status line labeled "lod:".  (This video was recorded before I made LODs conform to voxel volume boundaries.)

This was all "over-engineered", but I had fun implementing it for the most part.  The "fragment shading rates" graphics settings yields the best performance gains at the least cost of visual quality in my opinion, so the LOD feature is cool to have, but to a lesser extent for performance and more so for visual quality when set non-aggressively -- it reduces shimmering of distant voxel volumes because of the use of 3D mipmaps.

Wow, very informative thank you!