GMLscripts.com

Discuss and collaborate on GML scripts
Invert

You are not logged in.

#1 2013-09-30 03:13:14

davilillo
Member
Registered: 2013-09-30
Posts: 5

How to distort a surface using noise?

Hello all, im trying to make a world generator and im following the steps done here:
http://www.nolithius.com/game-developme … ion-teaser
But im stuck with the wind map thing, it says that has been inspired by:
http://www.dungeonleague.com/2010/03/28/wind-direction/

But i dont know even where to start, i made a surface similar to this:
thumbs_1269766192009.jpg


And found this perlin noise script:
http://gmc.yoyogames.com/index.php?showtopic=508813

And the idea is to distort the surface X times to achieve this effect:

thumbs_1269766197817.jpgthumbs_1269767918788.jpgthumbs_1269766218785.jpg
But i have no idea at how to apply the noise on the gradient to be able to distort the surface simulating wind patterns, i read on some places that i need to create 2 noise, one for each coordinate, and distort the gradient with the matching cells from the noises, any advice?
Thanks!

More info:
This is the step where i get lost:
http://www.dungeonleague.com/2010/02/11 … e-samples/
When i have to use 2 noise functions, "the second function is used to distort the coordinates before being put into the first function"
thumbs_1265945976293.jpg

Last edited by davilillo (2013-09-30 06:59:53)

Offline

#2 2013-09-30 08:46:53

xot
Administrator
Registered: 2007-08-18
Posts: 1,201

Re: How to distort a surface using noise?

That script probably won't be much help, but it's definitely the right direction.

The way it works is, each pixel has a UV coordinate pointing somewhere in the texture. Those coordinates are perturbed by random noise so that a different part of the texture is draw for that pixel.

It's a bit difficult to explain in detail without an understanding of solid texturing using noise functions. Basically, each point in space, or pixel on the screen, can be mapped to a point in the noise function. The noise function is random, but it is also static and continuous. When a coordinate is passed to it, it returns a noise value, a value which is always the same for any particular point and which varies gradually for nearby points.

Fractal noise, or fBm (fractal Brownian motion), is a way to layer multiple scales of noise (called octaves) into a function that has fractal characteristics. This is useful for simulating many natural phenomena. That's sort of what that GML script you linked is doing.

By mapping a pixel to a point in space and passing that point to the fBm function, we get a value from -1.0 to 1.0. We multiply this value by the amount of distortion we want and add that value to a texture coordinate, U or V. The images on the Dungeon League wind direction page show the effect of various levels of distortion. In order for U and V to be perturbed separately, we simply map the pixel to two different points in solid texture space.

Here is an example showing this in practice. It is very slow and could be sped up drastically by doing it with a shader.

hbU4AAB.jpg

http://host-a.net/u/xot/perturb-texture.gmz

In it you will find a GML implementation of Perlin's Improved Noise and an fBm function.

Last edited by xot (2013-09-30 09:37:13)


Abusing forum power since 1986.

Offline

#3 2013-09-30 09:14:03

xot
Administrator
Registered: 2007-08-18
Posts: 1,201

Re: How to distort a surface using noise?

Ah, I just saw your edit.

What he is doing is basically the same but instead of using the UV coordinates to map to a texture, he is plugging those coordinates back into the noise function. He then maps the value returned to a grayscale to make his image. He does not seem to be using fBm at all in this case.

Also, he doesn't mention it on the wind direction page, but it looks like the distortion value is modulated so that it is lower at the top and bottom edges (the poles).

distortion = maxdistortion * (1 - abs(2 * v - 1))

I've update the example to include this.

Last edited by xot (2013-09-30 09:44:23)


Abusing forum power since 1986.

Offline

#4 2013-09-30 11:19:18

davilillo
Member
Registered: 2013-09-30
Posts: 5

Re: How to distort a surface using noise?

Thank you very much! I downloaded the example and im going to study how do you did it, I will tell you if I manage to understand how it works wink

Offline

#5 2013-09-30 13:37:28

davilillo
Member
Registered: 2013-09-30
Posts: 5

Re: How to distort a surface using noise?

That was really advanced code  wacko

Some questions I have about the code, maybe you can help me to understand it better:

object0 - Create event
{
    maxdistortion = 0.4;    // maximum amount of distortion to apply
    octaves = 4;            // number of fractal noise octaves
    scale = 2/256;          // scale of fractal noise Why this number? I meant the 2, because 256 is the size of the texture right? If I make a smaller texture, should i change all 256 by 128 for example?
   
    noise_init();
   
    surfWind1 = -1;
    surfWind2 = -1;
    row = 0;
}


object0 - Draw event
{
    if (surface_exists(surfWind1) && surface_exists(surfWind2))
    {
        var i,j,k;
        if (row < 256)
        {
            // select surfWind1 for the texture
            var tex = surface_get_texture(surfWind1);
           
            draw_set_color(c_white);
            surface_set_target(surfWind2);
            draw_primitive_begin_texture(pr_pointlist,tex);
           
            // find the vertical texture coordinate for the pixel
            var v = row/256;
           
            // modulate the distortion to be minimal at the top and bottom edges
            var distortion = maxdistortion * (1 - abs(2*v-1));
           
            // draw a row
            for (i=0; i<256; i+=1)
            {                   
                // find the horizontal texture coodinate for the pixel
                var u = i / 256;
               
                // map the pixel to a point in solid texture spaceOk, the values here are related to the previous scale variable and the pixel position on the "grid"
                var px = scale * i;
                var py = scale * row;
                var pz = 0;
               
                // perturb the horizontal texture coordinate with fractal noise Here is where i imagine the horizontal distortion is produced right?
                var uu = u + distortion * fbm(px,py,pz,0.85,2.0,octaves);
               
                // map the pixel to a different point in solid texture space Why this values?
                px += 1.2;
                py += 1.5;
                pz += 1.8;
               
                // preturb the vertical texture coordinate with fractal noiseAnd here the vertical distortion
                var vv = v + distortion * fbm(px,py,pz,0.85,2.0,octaves);
               
                // draw the pixel with the perturbed texture coordinate
                draw_vertex_texture(i,row,uu,vv);
            }
            draw_primitive_end();
            surface_reset_target();
           
            // advance to next row
            row += 1;
        }
        draw_surface(surfWind1,0,0);
        draw_surface(surfWind2,256,0);
    }
    else
    {
        draw_set_color(c_red);
        draw_set_font(font0);
        draw_text(10,10,"SURFACE ERROR");
    }
}


Thank you very much!

Offline

#6 2013-09-30 15:03:23

xot
Administrator
Registered: 2007-08-18
Posts: 1,201

Re: How to distort a surface using noise?

A lot of the values are totally arbitrary.

scale = 2/256
That was selected ad hoc. The wind direction page says a size of 2 was used. It's unclear what exactly that means but I decided it was a scaling factor for the noise function. This has some bearing on the apparent size of the features in the generated image. I used 2 / 256 (size of the surface) and the results seemed to be pretty close to those on the web page. A larger value here will decrease the period of the noise and result in more compact features. If you used a different sized surface, 2 / size would result in more or less the same overall pattern, just scaled to fit the surface.

Where I map the pixel to a different point (px += 1.2, etc), I just chose a random offset for the point within the solid texture space. These could be literally any values. The goal is to chose two different points for U and V so that they aren't obviously linked. You could use an added offset for the first point as well to get a different resulting image that otherwise has the same characteristics. If the points used for U and V are the same, they will both be perturbed by the same values, and the result will have a strong diagonal bias.

Regarding fBm, the number of octaves controls the amount of overall detail in the result. The more octaves, the more fine detail, and the longer it takes to calculate. Each time you double the size of the output, you need to add one octave to maintain the same granularity of detail (assuming lacunarity = 2). This value should be an integer here, but there are other fBm functions that accept fractional octaves.

The H parameter sets the Hausdorff dimension. Fractals have a fractional dimension. That's where they get their name. A mountain range, can be thought of as something like a flat plane that has been crumpled up. The flatter it is, the closer it is to being topologically 2D. As it gets more crumpled, it approaches a solid 3D form. So, the dimension of the mountain's surface is interpreted as being somewhere between 2D and 3D. The H dimension is a measure of the difference between topological dimensions, and it varies from 0.0 to 1.0. The closer it is to 1.0, the flatter or smoother the result. The closer it is to 0.0, the more chaotic the result. I selected a value typical of mountains and coastlines.

The lacunarity parameter controls the relative scaling of each layer of noise. This is what gives fractal noise it's self-similarity. Usually you want this to be 2.0.

Feel free to experiment with different values.


Abusing forum power since 1986.

Offline

#7 2013-10-01 09:28:10

davilillo
Member
Registered: 2013-09-30
Posts: 5

Re: How to distort a surface using noise?

Thank you! I have so much to learn, still experimenting and trying to understand it completely

Offline

#8 2013-10-02 06:41:39

icuurd12b42
Member
Registered: 2008-12-11
Posts: 303

Re: How to distort a surface using noise?

So cool! I knew xot would help you out!

Offline

#9 2013-10-02 10:56:11

davilillo
Member
Registered: 2013-09-30
Posts: 5

Re: How to distort a surface using noise?

Yes! Thanks for pointing my in the right direction hehehe

Offline

Board footer

Powered by FluxBB