# how to use 2D noise with a voxel sphere

I have a bunch of voxels, lets just say 64x64x64, that I use to create a sphere/planet. This works very well, but once I try to apply noise to create a more interesting terrain things go wrong.

3D noise works fine, but I don't always want to create terrain with caves, overhangs etc, so I figured in those cases 2D noise would be a good solution, but I can't figure out how to use it correctly.

I tried this, where pos (world position) is a float3 and x and y are the input values for the noise function:

float x = math.acos(pos.z / math.length(pos));
float y = math.atan(pos.y / pos.x);


That results in a very noticeable seam along one axis and pinching at the poles though.

Is there any way I can convert my 3D world position into 2D coordinates, so that the noise function (Perlin or Simplex) will produce a seamless result without pinching? I don't mind in the least if this causes symmetry or repeating features.

There is no perfect way to map the surface of a sphere to a flat plane - you always get seams or stretching/pinching somewhere. This is why map projections are such a rich subject - every one offers different trade-offs that are good for some uses and less good for others.

A better route for your purposes is probably to continue using your 3D noise, but sample just a 2D manifold out of it:

GetSphereSurfaceNoise(float3 worldPosition, float3 center) {
float3 surfacePosition = normalize(worldPosition - center) * noiseRadius;
return GetNoise(surfacePosition);
}


This ensures all samples along a ray radiating out from the center of your sphere get the same noise value, so you can raise/lower whole columns of terrain without creating caves/overhangs, and the result will be continuous & seamless all around your sphere.

Tuning the noiseRadius parameter lets you control the density of the noise (scaling up or down the 2D shell you're sampling from in noise space)