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:
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!