Procedural voxel planet generation - precision problems

Started by
0 comments, last by JoeJ 7 years ago

Hi!

I'd like to render a procedurally-generated Earth-sized voxel planet (i.e. not using heightmaps and quadtrees).

I have mostly working view-dependent octree-based crack-free rendering of a gigantic smooth (i.e. not blocky/Minecraftish) isosurface.

If I make the world too big (16 LoDs), floating-point precision (?) starts to break down: the surface is no longer smooth but dimpled, edges become jagged, and large ugly-looking black spots appear (wrong normals?).

1) How are such precision problems dealt with when generating very large terrains?

Should I simply use 'doubles' as e.g. in the spacesim game Pioneer?

2) My isosurface sampling is slow, it runs on CPU and is implemented via an abstract 'SDF' interface, with lots of 'virtual's, etc.

How should procedural generation be implemented on GPU? Should I use compute shaders or OpenCL? Should I post new 'GenerateChunk' requests in the current frame and retrieve them in the next frame to avoid stalls? Should I use 'doubles' on the GPU?

Advertisement
Doubles are not really an option on GPU, too slow.
Eventually you can get enough precision by using a world with origin near camera and different scales at different LODs, or something like a logarithmic scale relative to origin.
I guess the additianl need to transform the whole scene when the origin changes is still a lot better than using doubles.

Compute shaders and OpenCL 1.2 have similar feature level on the shader side, so your decission should depend only on API and performance.

Personally i work on a large compute project with Vulkan / OpenCL code path.
I use the same shader code for both (using a preprocessor): Vulkan takes 2ms - OpenCL takes 3ms. (the difference depends on overall complexity)
The speedup comes from precompiled command buffers and indirect dispatch (OpenCL 1.2 has neither of those features)

OpenGL has indirect dispatch, so it should be better than CL but in my experience this was not the case some years back.
NV compute shaders performed very poorly - CL was almost two times faster.
This may have changed in the meantime as i hope. (No experience with DirectX)

OpenCL has no interop with Vulkan or DX12, so it's no option for those at the moment.
(It's pretty unlikely you'd pick OpenCL, but may be still worth a look)


I suggest you first rewrite your isosurface stuff on CPU but with GPU in mind:
Use a procedural programming style where each function becomes a shader later. (Avoid class methods at all, this just hides what data you're working with. In other words: more C than C++)
Already think about how to use LDS and how to avoid divergence.
Avoid long functions that may use too much registers.

You do not need to share the same data layout in memory for CPU / GPU code branches. Instead use utility functions that convert between both.

This topic is closed to new replies.

Advertisement