I'm developing a game that procedurally generates terrains with a voxel engine. These terrains are essentially flat cubes that trail off into infinity on the x and z axes. y is basically the altitude, so y=0 is the "center" of the world and moving up along y would travel from underground, to the surface, and on into space.

I want to convert these cubes into spheres (so that they are more like planets). My input into this algorithm would be the radius of the sphere, and the xyz coordinates of the voxel I want to sample. This would be unrolled into searching the original cubic structure.

I understand this operation would have distortions, and cause warping at the seams where the cube wraps back in on itself on the "bottom" of the sphere. Points sampled at lower altitudes (distance from the center of the sphere) would be pinched together, and points sampled at higher altitudes would tend to lose resolution up to a point where two voxels that would normally be side by side in the cubic structure would be far apart in the spherical structure.

Here is a (crudely drawn) 2d representation of what I'm trying to accomplish:

Cube and Sphere

The labeled points in both images should map together. Due to the "pinching" nature of this process, E A and F would merge into each other, and B and C would merge into each other. On the surface, the area between B and D and the area between D and C would stretch out.

The radius would essentially act to crop the infinite nature of the voxel structure on the x an z axes. The voxel structure would still be effectively infinite on the y axes (from 0 to +infinity).

If I want to know what voxel to draw at coordinates (x,y,z), and I know radius R and center of the sphere (cx, cy, cz), I think I can use the distance from the center of the sphere to my sample coordinate as the y' value for sampling the voxel structure:

y' = sqrt((cx-x)^2 + (cy-y)^2 + (cz-z)^2)

The point I'm not sure about is how to calculate x' and z', which all together would be used to query the voxel structure on the left.

SampleVoxelData(x', y', z') => returns voxel at that location

I'd appreciate any insights or suggestions!

  • 1
    \$\begingroup\$ This is an unusual mapping to use. Usually when we want to map a sphere to a cubic structure we'll use effectively a cubemap (so you'd have 6 voxel terrains, one of each face of the master cube). Trying to wrap just one cube around the sphere would crunch the sides of the cube into a singularity. If you try to map the +x face to the -x face making it wrap in a cylinder, then there's nowhere left for the z+/- faces to connect without crossing (or making a torus) \$\endgroup\$ – DMGregory Jan 10 at 20:01

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.