ashima / webgl-noise

Procedural Noise Shader Routines compatible with WebGL
MIT License
2.78k stars 301 forks source link

6D noise #23

Closed unicomp21 closed 3 years ago

unicomp21 commented 3 years ago

For generating 3D tiles on the fly, what about creating a 6D noise function?

stegu commented 3 years ago

6-D gradient noise on a grid would have a very unequal density of grid points, even when using a simplex grid. The problem with "simplex noise" being flat gray in large areas is apparent already in 2-D slices of 3-D noise, it becomes a problem in 2-D slices of 4-D noise, and it would be considerably worse in 3-D slices of 6-D noise. We would probably need to find a different grid than the simplex grid in 6-D space to make a good looking noise field. I am not saying it is not worth trying, but I am saying I won't spend time on it at the moment, because I would not be able to come up with a good solution with the very limited time and energy I can muster at the moment. I think the classic periodic noise on a 3D Cartesian grid solves this particular problem better.

Incidentally, there are ways to make a 3-D simplex grid tile over an axis-aligned cube. One I have tried as a first step to my ongoing struggle to find time to implement a tiling simplex 3-D noise function to use for "flow noise" is to use these vectors for the simplex cube edges:

(1.0, 0.0, 0.0), (-0.5, 1.0, 0.5), (-0.5,-1.0, 0.5)

Transforming from (x,y,z) to coordinates of that grid and back involves these two matrices (Mi is the inverse of M):

const mat3 M = mat3(1.0, 0.0, 0.0, 0.0, 0.5,-0.5, 1.0, 1.0, 1.0); const mat3 Mi = mat3(1.0, 0.0, 0.0, -0.5, 1.0, 0.5, -0.5,-1.0, 0.5); This works, and this not-quite-optimal but reasonably good simplex grid will tile neatly on any cube with even-numbered integer sizes in x, y, z. In fact, any integer period works for x and z, only the y period has to be even.

The disadvantage is that the grid is axis-aligned, by design, which gives the noise function a strong tendency to show a pattern in axis-aligned 2-D slices. Ken Perlin's 3-D simplex grid is rotated and has no such axis alignments, which hides that problem in most situations. (You can still find cut planes where his grid does show the same kind of pattern, but you would be unlikely to hit any of those angles by accident.) The grid suggested above could be rotated as well, of course, but that would defeat its purpose of making it tile over an (x,y,z) Cartesian grid. Tricks could be played with using rational angles and making the grid tile over a larger period, but I have not come that far in my experiments, and I think it would be a too strong restriction on tiled 3-D noise to require that you have periods that are multiples of some larger integer, somewhere in the dozens or so.

Relevant previous work to get around this can be found in the implementations of "rational tangent halftoning" for PostScript 2, where you don't necessarily get the exact period and angle you ask for in a halftone pattern, but it would need to be extended from 2-D to 3-D, which is a non-trivial task.

I had an article about "3-D tiling simplex noise with rotating gradients" in the works based on the above grid, but I was taken ill with Covid-19 before I could finish the implementation, and I am still struggling with the after effects, to the extent that I can't do any useful work at all at the moment. This will hopefully pass.

unicomp21 commented 3 years ago

Thanks @stegu, much appreciated. Hope you're feeling better soon.