-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to use periodic fbm/rmf/turbulence? #3
Comments
For periodic, tileable fBm noise, you need each frequency to be an integer
multiple of the tile size. You can still ask for an arbitrary lacunarity,
but then you need to round each frequency (and the tiling period) to an
integer in the loop. With that fix, you should be able to use 2-D periodic
noise for 2-D tiling fBm without being restricted to a lacunarity of
exactly 2.0. However, the usual problems with lacunarity 2.0 will still be
present to some extent: all zero crossings will coincide between the
components. To help avoid the related artefacts, you could try adding a
random 2-D offset to the texcoords of each consecutive term in the sum to
move the zero crossings away from each other. That should take care of most
artifacts, I hope.
Good luck, and let me know if I can be of any further help!
/Stefan Gustavson
…On 2 Jan 2017 16:50, "David Asmuth" ***@***.***> wrote:
Hi, first thanks for the great work!
I need periodic 2D noise for a planet texture/heightmap.
My current solution is the following.
Take the UV and do this:
vec4 tile(in vec2 pos) { return vec4( offset + cos(pos.x * 2.0 * PI) *
inResolution.x / (2.0 * PI), offset + cos(pos.y * 2.0 * PI) *
inResolution.y / (2.0 * PI), offset + sin(pos.x * 2.0 * PI) *
inResolution.x / (2.0 * PI), offset + sin(pos.y * 2.0 * PI) *
inResolution.y / (2.0 * PI) ); }
The resulting 4D position is the used in 4D simplex noise as position.
This leads to sweet tileable noise.
This is how I doing fractal brownian motion for example:
`float fbm(in vec4 pos, in int octaves, in float frequency, in float
lacunarity, in float persistence) {
frequency /= inResolution.x;
float currentWeight = 1.0;
float totalWeights = 0.0;
float result = 0.0;
for (int i = 0; i < MAX_OCTAVES; i++) {
if (i >= octaves) break;
result += snoise(vec4(pos.x * frequency, pos.y * frequency, pos.z *
frequency, pos.w * frequency)) * currentWeight;
totalWeights += currentWeight;
currentWeight *= persistence;
frequency *= lacunarity;
}
return result / totalWeights;
}`
But this is 4D noise computation complexity just for 2D noise. :(
I would like to use your periodic 2d simplex noise instead, but I have
problems to use it in context of fractal brownian motion, ridgit multi
fractals and turbulence.
This is my approach so far:
`float fbm2(in vec2 pos, in int octaves, in float frequency, in float
lacunarity, in float persistence) {
float currentWeight = 1.0;
float totalWeights = 0.0;
float result = 0.0;
for (int i = 0; i < MAX_OCTAVES; i++) {
if (i >= octaves) break;
result += psnoise((pos)*pow(2.0,float(i)),vec2(2.0,2.0)*pow(2.0,
float(i))) * currentWeight;
totalWeights += currentWeight;
currentWeight *= persistence;
frequency *= lacunarity;
}
return result / totalWeights;
}`
This works, but completly skips the frequency and lacunarity parameters.
As soon as I take frequency or lacunarity in account (ex. multiply by
position like in 4D fbm) its not tileable anymore :(
So my question is: is there a way to use periodic noise and be still able
to set arbitrary frequency and lacunarity?
something like: fbm2(pos, 6, 1.0, 2.13727, 0.507123)
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#3>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAplas3C-6mGb0bad7mqUPHsezAUXEezks5rORy9gaJpZM4LZFYV>
.
|
Thank you for your help, that works really well! :) Btw. For my OpenCL noise library I provided a 255 permutation table. I would like to generate a permutation table rather than using mod289 here too. Is it possible? I had in mind to generate on the CPU a 17x17 texture with red containing the values and green containing the overflow (289 is a bit too much for one channel). So in the shader I will do a texture lookup instead of mod289. The reason behind this is a tradeoff between weaker performance but having the ability to provide a seed and being capable to generate 289 factorial planets. |
The polynomial permutation (34*x*x+x) mod 289 can certainly be replaced
with a permutation table if you like. The only problem with that solution
is that it requires a texture, and we wanted our implementation to be free
from any setup and dependencies on external data, as well as entirely free
from texture lookups. We wanted it to be "computational" and make good use
of the often under-utilised ALU resources in a modern GPU. In reality, a
texture-based permutation is often faster, at least when using a desktop
GPU that isn't already choked with texture lookups elsewhere in the same
shader.
Unless you want a pixel-perfect drop-in replacement for the "mod289" noise,
there is no need to stick with the 289-length permutation if you use a
table. Just do a regular 256-element permutation like most classic noise
implementations do, and use a uint8 single channel texture. You can even
play a trick I used in a previous experiment and create a 256x256 texture
that does the permutation on x and y simultaneously. The permutation is
then a single 2-D texture lookup instead of two sequential 1-D lookups:
"permute((permute(x)+y) mod 256)" becomes simply "permute(x,y)".
My old demo implementation of that kind of texture-based noise is linked
from http://github.com/ashima/webgl-noise/wiki, under the headline "Other
noise implementations". The permutation texture lookup in the shader could
be made much less complicated (no mapping back and forth between the ranges
0..255 and 0..1) if you are on an OpenGL platform with the luxury of
integer texture formats and integer-indexed texture rectangles. WebGL
doesn't have that by default yet, and my old texture-based code was written
long before texture rectangles and integer texture formats were available.
/Stefan G
|
Hi Stefan, thank you again for this great explanation. I will implement the permTexture as you did in your older shaders. I'm using WebGL which, as you already mentioned, doesn't support int-textures and WebGL 2 will need another year to reach critical mass, so I will have to stick with the float approach for now. |
This thread is informative, so I'm keeping it open. |
I recently did a version of 2-D simplex noise (with flow noise capabilities, i.e. rotating gradients and an analytic derivative) that lives natively on a sphere, in a Fibonacci spiral grid. Let me know if you have any interest in that. It's not super optimized right now, and there are some limitations to how far it scales into fine detail, but it's definitely useful for texturing a sphere without seams. |
Hi, first thanks for the great work!
I need periodic 2D noise for a planet texture/heightmap.
My current solution is the following.
Take the UV and do this:
The resulting 4D position is the used in 4D simplex noise as position. This leads to sweet tileable noise.
This is how I doing fractal brownian motion for example:
But this is 4D noise computation complexity just for 2D noise. :(
I would like to use your periodic 2d simplex noise instead, but I have problems to use it in context of fractal brownian motion, ridgit multi fractals and turbulence.
This is my approach so far:
This works, but completly skips the frequency and lacunarity parameters.
As soon as I take frequency or lacunarity in account (ex. multiply by position like in 4D fbm) its not tileable anymore :(
So my question is: is there a way to use periodic noise and be still able to set arbitrary frequency and lacunarity?
something like:
This is how it looks with octaves as frequency and below my approach to use the parameters:
The text was updated successfully, but these errors were encountered: