17
$\begingroup$

I would like to generate procedural noise on the surface of a sphere (e.g. to procedurally generate planets or marble-textured balls). Of course, I could just take a standard noise algorithm and map it onto the sphere, but this has all the issues of projecting a plane onto a sphere, like distortions on the poles or elsewhere.

I suppose I could generate volume noise and "cut out" the sphere, but this seems unnecessarily inefficient - and if the noise has some grid-based artefacts, these would still not appear uniformly on the sphere. Furthermore, at least in the case of Simplex noise, cutting 2D slices out of 3D noise generally looks different than generating 2D noise right away.

Is there any way to avoid these issues, e.g. by generating noise natively on the sphere? The noise should have at least the quality of Perlin noise, ideally that of Simplex noise.

$\endgroup$
4
  • $\begingroup$ Maybe triplanar projection, as seen in GPU Gems 3? The question is whether the noise would look blurry or otherwise undesirable when it's blending between different projections. $\endgroup$ Commented Aug 5, 2015 at 8:37
  • $\begingroup$ I added another possible method to my post. It may be worth clarifying your question with more detailed requirements. i.e. why does a 2D slice of 3D noise not satisfy your visual requirements? What are your performance requirements? $\endgroup$ Commented Aug 11, 2015 at 15:02
  • $\begingroup$ @JohnCalsbeek Honestly, I don't have any hard requirements at hand. This was just a question I was curious about which I thought I'd give a go for the private beta. Of course, cutting a 2D slice out of 3D noise will be sufficient for many applications, but I'm sure it will have some performance impact and anisotropies (which may or may not be noticeable). "Cutting the sphere out of 3D noise is your best option, because..." is definitely a valid answer. $\endgroup$ Commented Aug 12, 2015 at 11:44
  • $\begingroup$ You might check out this shadertoy which does noise on a sphere: shadertoy.com/view/4sfGzS $\endgroup$
    – Alan Wolfe
    Commented Aug 17, 2015 at 14:58

1 Answer 1

17
+50
$\begingroup$

I'd consider just going with 3D noise and evaluating it on the surface of the sphere.

For gradient noise which is naturally in the domain of the surface of the sphere, you need a regular pattern of sample points on the surface that have natural connectivity information, with roughly equal area in each cell, so you can interpolate or sum adjacent values. I wonder if something like a Fibonacci grid might work:

Fibonacci grid on the surface of a sphere

I haven't chewed through the math to determine how much work it would be to figure out the indices of and distance to your four neighbors (I don't even know if you end up having four well-defined neighbors in all cases), and I suspect it may be less efficient than simply using 3D noise.

Edit: Someone else has chewed through the math! See this new paper on Spherical Fibonacci Mapping. It seems that it would be straightforward to adapt it to sphere noise.


If you are rendering a sphere, not just evaluating noise on the surface of a sphere, and are fine with tessellating your sphere to the resolution of your noise lattice, you can create a geodesic grid on the surface of the sphere (a subdivided icosahedron, usually):

Geodesic sphere

Each vertex of the sphere can have a randomly generated gradient for gradient noise. To get this information to the pixel shader (unless you want straightforward interpolation like value noise), you may need a technique like this article's wireframe rendering with barycentric coordinates: do unindexed rendering, with each vertex containing the barycentric coordinates of that vertex in the triangle. You can then read from SV_PrimitiveID (or the OpenGL equivalent) in the pixel shader, read the three noise gradients from the vertices based on what triangle you are on, and use whatever noise calculation you like using the interpolated barycentric coordinates.

I think the most difficult part of this method is coming up with a scheme to map your triangle ID to three samples in order to look up the noise values at each vertex.

If you need multiple octaves of noise or noise at a finer resolution than your sphere model, you may be able to do a coarse geodesic grid with vertices and do a few levels of subdivision in the pixel shader. i.e. from the barycentric coordinates, figure out which subdivided triangle you would be in if the mesh was further tessellated, and then figure out what the primitive ID and barycentric coordinates would be for that triangle.

$\endgroup$
3
  • 3
    $\begingroup$ I'd never heard of Fibonacci grids before; that's pretty cool! $\endgroup$ Commented Aug 5, 2015 at 21:09
  • $\begingroup$ That's a fascinating paper. It looks like you can adjust the parameters to give nearer to a square grid or a hexagonal grid, which would allow different approaches to noise generation. $\endgroup$ Commented Aug 9, 2015 at 22:43
  • $\begingroup$ I had some not-bad results interpolating near the edges of the tile (edge-wrapped), but it depends on what effect you're trying to achieve and the exact noise parameters. Works great for somewhat blurry noise, not so good with spikey/fine-grained ones. $\endgroup$
    – user379
    Commented Aug 13, 2015 at 3:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.