Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (109)
games submitted by our members
Games in WIP (536)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  The output of noise  (Read 3722 times)
0 Members and 1 Guest are viewing this topic.
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Posted 2011-04-07 17:49:01 »

I have been experimenting with a variety of noise over the last few days, from perlin, simplex, value, etc...

The problem I have come, is not in the base noise, but how to output it.
Whenever I generate anything, it always appear pure static, and for the longest time, I thought I was doing something wrong. Until I realized its not supposed to be anything but static.  Its the manipulation of that noise that produces what I want.

That's when I learned more properly about octaves, persistence, frequency, periods. Also about fractal(fractional?) brownian motion.

I have looked at a whole lot libs/examples, (unfortunately, most of them are in other languages) and tried my best to convert them to Java.

Unfortunately, All I can ever get is the just plain static.(pure noise)

I just want smooth(cloudy/terrain) looking output.

For the sake of argument, I am going to be using Improved noise from perlins website and/or simplex noise(2D) from
http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf  (bottom of page/source)  (removed the 3D and 4D components)
http://mrl.nyu.edu/~perlin/noise/ (improved noise from perlin)


Although I have tried several variations/functions of SmoothNoise, I am going to pick one to show
1  
2  
3  
4  
double corners = ( Noise.noise(i-1, j-1)+Noise.noise(i+1, j-1)+Noise.noise(i-1, j+1)+Noise.noise(i+1, j+1) ) / 16;
          double sides   = ( Noise.noise(i-1, j)  +Noise.noise(i+1, j)  +Noise.noise(i, j-1)  +Noise.noise(i, j+1) ) /  8;
          double center  =  Noise.noise(i, j) / 4;
          map[i][j] = corners+sides+center;

Once again, I am aware of several interpolation methods,  either a basic one or cosine, etc...
http://paulbourke.net/miscellaneous/interpolation/
I am just going to pick a basic one for now.
1  
2  
3  
public float interpolate(float d, float e, float alpha){
      return (float) ((1-alpha)*d+alpha*e);
   }

I also tried using
1  
2  
3  
4  
5  
6  
  public float Cosine_Interpolate(float a, float b, float x){
            float ft = (x * 3.1415927f);
            float f = (float) ((1 - Math.cos(ft)) * .5);

            return  a*(1-f) + b*f;
            }


Frequency is 2^octave
amplitude is persistence^octave

http://devmag.org.za/2009/04/25/perlin-noise/

http://freespace.virgin.net/hugo.elias/models/m_perlin.htm  (scroll down to the [2-dimensional Perlin Noise Pseudocode] section) as my main reference.


The problem now comes in actually producing the data. I am filling everything into a 512x512 array.
I am producing an output using LWJGL and GL_Points,  1 colored point for each point in the array. Also tried both with grayscale,  color gradients, manual scaling(i.e. anything in ranges produce 1 color, (so it only outputs 3-4 total colors, and not gradients) 

I just am starting to get extremely frustrated.   Does anyone have any "non easily found website references"
or some extremely simple to the point functioning equation that takes input noise and does the smooth,interpolate, octaves, etc... properly?

I know its not the easiest topic to be jumping at.
I am probably overlooking something really stupid, but I am just a little lost.




"Experience is what you get when you did not get what you wanted"
Offline SimonH
« Reply #1 - Posted 2011-04-07 18:33:16 »

Here's the basic code I use in Stickmenwars2;
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
   float persistence=1/8f;
   int numberOfOctaves=3;
   float hScale=0.155f;
   float vScale=22.6f;
        ...

        public float getHeight(float x, float z)
   {
      float height=0;
      float frequency;
      float amplitude;

                 float p=persistence;
                 int n=numberOfOctaves-1;

                 x*=hScale;
               z*=hScale;

                 for (int i=0;i<n;i++)
                 {
         frequency=2*i;
                     amplitude=p*i;
                   height=height+interpolatedNoise(x*frequency,z*frequency)*amplitude;
                 }
                 height*=0.3f;
      return height*vScale-1f;
   }


   private float interpolatedNoise(float x, float y)
   {
      if (x<0)
      {
         x=-x;
      }
      if (y<0)
      {
         y=-y;
      }
      int integer_X=(int)x;
      float fractional_X = x-integer_X;

      int integer_Y=(int)y;
      float fractional_Y=y-integer_Y;

      float v1 = noise(integer_X,integer_Y);
      float v2 = noise(integer_X+1,integer_Y);
      float v3 = noise(integer_X,integer_Y+1);
      float v4 = noise(integer_X+1,integer_Y+1);

      float i1=interpolate(v1,v2,fractional_X);
      float i2=interpolate(v3,v4,fractional_X);

      return interpolate(i1,i2,fractional_Y);
   }

   private float interpolate(float a, float b, float x)
   {
      // linear interpolation
     return  a*(1-x) + b*x;
   }

   public float noise(int x, int y)
   {
       int n=x+y*57;
       n=(n<<13)^n;
       return (1.0f-((n*(n*n*15731+789221)+1376312589)&0x7fffffff)/1073741824f);
   }

This should give you a smooth rolling landscape. By mixing several different getHeight() functions together you can add in mountains, lakes &c.

People make games and games make people
Offline DzzD
« Reply #2 - Posted 2011-04-07 18:35:20 »

dont know if it can help, but I write this one recently for a project : http://www.java-gaming.org/topics/fastest-perlinnoise-improved-version-bicubic-amp-bilinear-grad-amp-value-noise/23771/view.html

basically once compiled what you can do to get something (blue clouds) is simply :
pixelx[x+y*width]=FastNoise.noise(x*0.01+y*0.01);

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline DzzD
« Reply #3 - Posted 2011-04-07 18:37:36 »

here is another one I wrote earlier that you can download http://demo.dzzd.net/PERLINSample/

source  code are  provided and it is based on hugo elias explanation, (as far as I remember all interpolation are available inside but not sure)

Offline endolf

JGO Coder


Medals: 7


Current project release date: sometime in 3003


« Reply #4 - Posted 2011-04-07 18:47:52 »

Hi

I wrote a simple demo using ardor3d that generates nebula like effects for a space game. The demo is here and you can browse the source here and the code that maps noise into pixels is here

HTH

Endolf

Online Roquen
« Reply #5 - Posted 2011-04-07 18:48:07 »

When you want to animate noise, you need to evaluate in one higher dimension than your target and "move" your sample points through this extra dimension.
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #6 - Posted 2011-04-07 18:56:56 »

For a 2D terrain, I know I'd need a 3D array to animate the 2D terrain shifting around

but for right now I just want a static 2D image. non animated.

When you want to animate noise, you need to evaluate in one higher dimension than your target and "move" your sample points through this extra dimension.

"Experience is what you get when you did not get what you wanted"
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #7 - Posted 2011-04-07 18:57:26 »

Just to be clear, this is how I set it up

tried default persistence/octaves/hScale/vScale values as well as tweaking them a little bit

for i loop to 512
for j loop to 512

1  
map[i][j] = getHeight( i , j );


though I feel like I May set it up wrong because you have float x and z, whereas I am assuming its x and y?  I am a little confused on this point



So either I am doing something wrong or not doing something I need too? or perhaps its my method of output thats messed up?

Because I still get variations of near pure noise.  There appears to show no flow or rises/falls in here at all.


edit: checking out 2 other references now



Here's the basic code I use in Stickmenwars2;
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
   float persistence=1/8f;
   int numberOfOctaves=3;
   float hScale=0.155f;
   float vScale=22.6f;
        ...

        public float getHeight(float x, float z)
   {
      float height=0;
      float frequency;
      float amplitude;

                 float p=persistence;
                 int n=numberOfOctaves-1;

                 x*=hScale;
               z*=hScale;

                 for (int i=0;i<n;i++)
                 {
         frequency=2*i;
                     amplitude=p*i;
                   height=height+interpolatedNoise(x*frequency,z*frequency)*amplitude;
                 }
                 height*=0.3f;
      return height*vScale-1f;
   }


   private float interpolatedNoise(float x, float y)
   {
      if (x<0)
      {
         x=-x;
      }
      if (y<0)
      {
         y=-y;
      }
      int integer_X=(int)x;
      float fractional_X = x-integer_X;

      int integer_Y=(int)y;
      float fractional_Y=y-integer_Y;

      float v1 = noise(integer_X,integer_Y);
      float v2 = noise(integer_X+1,integer_Y);
      float v3 = noise(integer_X,integer_Y+1);
      float v4 = noise(integer_X+1,integer_Y+1);

      float i1=interpolate(v1,v2,fractional_X);
      float i2=interpolate(v3,v4,fractional_X);

      return interpolate(i1,i2,fractional_Y);
   }

   private float interpolate(float a, float b, float x)
   {
      // linear interpolation
     return  a*(1-x) + b*x;
   }

   public float noise(int x, int y)
   {
       int n=x+y*57;
       n=(n<<13)^n;
       return (1.0f-((n*(n*n*15731+789221)+1376312589)&0x7fffffff)/1073741824f);
   }

This should give you a smooth rolling landscape. By mixing several different getHeight() functions together you can add in mountains, lakes &c.

"Experience is what you get when you did not get what you wanted"
Offline DzzD
« Reply #8 - Posted 2011-04-07 19:00:49 »

a guess => just scale down your input

noise(x*k,y*k) with k==0.01 or such

Offline Addictman

Senior Member


Medals: 3
Projects: 1


Java games rock!


« Reply #9 - Posted 2011-04-07 19:10:03 »

ShannonSmith here has a nice tutorial on noise here: http://www.angryoctopus.co.nz/?page_id=11

It works very well. I made some minor adjustments, and made a "world map generator" here: http://nardogames.com/Tools/MapGenerator
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline SimonH
« Reply #10 - Posted 2011-04-07 19:10:55 »

I used x & z because SMW2 is 3D so my y is height.
The code I posted gives me a nice smooth landscape with heights between -1 and +1.
Maybe your rendering code is faulty?

People make games and games make people
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #11 - Posted 2011-04-07 19:21:00 »

I used x & z because SMW2 is 3D so my y is height.
The code I posted gives me a nice smooth landscape with heights between -1 and +1.
Maybe your rendering code is faulty?


Its very possible my rendering code is faulty.

num=512;
map[512][512];


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
for(int i=0;i<num;i++){
            for(int j=0;j<num;j++){
               
                GL11.glPointSize(1f);

                GL11.glBegin(GL11.GL_POINTS);

                GL11.glVertex3f(i, j, 0f);
                GL11.glColor3f(map[i][j], map[i][j], map[i][j]);
                             
                GL11.glEnd();
            }
        }


assume each point is a single pixel.
the color3f should produce a grayscale(black/white) picture,  of 255 possible values.  Should be darker in lower areas and brighter in higher areas?  The range of color3f should be from 0.0f to 1.0f  


Also through debugging, I am manually verifying that my values of map fall between 0 and 1. So I have them scaled properly.

edit:
  SimonH, the original code you gave, I copied/pasted exact. The only thing changed was it sometimes went over 1.0 so I tried 2 methods, 1 was halve it(0.5*) and also tried putting a if >1 then =1.   Also in one test, where it produced negative values, I made used Math.abs();

http://www.newrog.com/images/test.png  is what I am getting it, or variations close to this
http://www.newrog.com/images/PerlinNoise2d.png is something like what I want

"Experience is what you get when you did not get what you wanted"
Offline SimonH
« Reply #12 - Posted 2011-04-07 19:49:40 »

Should work OK - try decreasing the hScale to 0.001f - about 10 times zoomed in.

People make games and games make people
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #13 - Posted 2011-04-07 20:05:46 »

http://newrog.com/images/test2.png

Its closer, but now its generating weird horizontal/vertical artifacts.

I tried playing with the hScale, vScale, Octaves, Persistence, As well as the "final number" scaled.

I can get a variety of things, but none of them look even remotely close to what I see online and elsewhere.  And nothing that feels like "rolling hills, valleys, mountains"  

edit:
http://newrog.com/images/test3.png  
I am going to assume it now has to do with tweaking the values more and more.  I am only modifying 5 values(persistence, octaves, hscale, vscale, and "final value"(final value sometimes falls above 1.0, so must be reduced)

I feel like its generating some odd behavior, horizontal/vertical things. As well as once, it was weird blob top left, with streaks shooting out like a starburst from top left, outward right side and bottom side.


edit 2:
on hugos site, he has
frequency = 2 ^ i
amplitude = persistence ^ i

but in your code, you have frequency 2*i and amplitude = persistence * i
Would this cause much problem/trouble?  Multiplicative vs exponential  Once your in higher octaves, itll behave differently.


edit 3:

I changed freq and ampl to Math.pow's and I am using

float persistence=0.95f;
int numberOfOctaves=8;
float hScale=0.008f;
float vScale=6.6f;

With a final
map[j]=(Math.abs(getHeight(i, j))/numberOfOctaves); //occasionally would multiply the whole thing by 0.5f to 0.95f

And I am now getting something, reasonably close to what I wanted.
http://www.newrog.com/images/finally.png
I believe now, its just a matter of tweaking constants.



edit 4:
   float persistence=0.6f;
   int numberOfOctaves=12;
   float hScale=0.008f;
   float vScale=15.6f;
http://www.newrog.com/images/finally2.PNG

Thank you all! I am really close to my goal now!



"Experience is what you get when you did not get what you wanted"
Offline SimonH
« Reply #14 - Posted 2011-04-07 20:28:04 »

Its closer, but now its generating weird horizontal/vertical artifacts.
That's my linear interpolation - I used that because I'm using polys and I wanted the heights to match the poly surfaces.

Anyway, you got there in the end! It's fun stuff to play with, isn't it?  Grin

People make games and games make people
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #15 - Posted 2011-04-07 20:39:12 »

Its closer, but now its generating weird horizontal/vertical artifacts.
That's my linear interpolation - I used that because I'm using polys and I wanted the heights to match the poly surfaces.

Anyway, you got there in the end! It's fun stuff to play with, isn't it?  Grin

ah So I'll try a cosine or another interpolation and see what I can come up with.


I have seen it elsewhere, but is there a benefit/downside to using the following?  (hash function?)
1  
2  
3  
4  
5  
6  
public float noise(int x, int y)
{
    int n=x+y*57;
    n=(n<<13)^n;
    return (1.0f-((n*(n*n*15731+789221)+1376312589)&0x7fffffff)/1073741824f);
}


over another variation of base noise?  such as simplex or perlin.
Its the 1 part of the whole thing that makes me scratch my head over.

My "best guess as to why"
I believe its called a PRNG for Pseudo Random Number generator.  I believe you chose it, aside from what was found, is that its much "faster" then perlin or simplex.  However, it has a limited output appearance (It gives similiar/same look)  which is fine, depending on what your goal is.

Changing the large numbers, has a small but slightly noticeable effect(depends how much you change)
to get the biggest change using the above, is to change the integer multiplication on the n value.
Alternatively, I could offset my x/y values to get various appearances.


"Experience is what you get when you did not get what you wanted"
Offline endolf

JGO Coder


Medals: 7


Current project release date: sometime in 3003


« Reply #16 - Posted 2011-04-07 21:07:26 »

Using the noise functions from perlin & co you'll find you get smooth gradients (depending on the 'zoom'), which means you can do rolling mountains, with smoothness, and then as you increase the fbm octaves you can give localised spikes showing more detail.

Your rng will give a random value for each vertex, rather than a value along a gradient. Which is why clouds and landscapes use noise functions rather than just pure rngs

Endolf

Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #17 - Posted 2011-04-07 21:18:41 »

Using the noise functions from perlin & co you'll find you get smooth gradients (depending on the 'zoom'), which means you can do rolling mountains, with smoothness, and then as you increase the fbm octaves you can give localised spikes showing more detail.

Your rng will give a random value for each vertex, rather than a value along a gradient. Which is why clouds and landscapes use noise functions rather than just pure rngs

Endolf


So what you are saying, is it would probably be better to rewrite/adjust the previous code so that it uses a more appropriate noise function, such as simplex or perlin. instead of the rng that is above.  I tried swapping it out 1:1 for the base noise, but it doesn't give me anything usable, so numbers need to change somewhere.  swapping it out for improved noise from perlin, gives me the same number in all spots, so something will need to be tweaked.

I had planned to do a 3-10 seconds of loading(calculating), and then a perpetual background cluster calculation, depending on movement, so it doesn't have to be "near instant".

edit:
The journey
http://www.newrog.com/images/test.jpg
http://www.newrog.com/images/test2.jpg
http://www.newrog.com/images/test3.jpg
http://www.newrog.com/images/finally.jpg
http://www.newrog.com/images/finally2.jpg

edit:
I finally reached my first major milestone!





"Experience is what you get when you did not get what you wanted"
Offline SimonH
« Reply #18 - Posted 2011-04-07 22:05:38 »

I believe its called a PRNG for Pseudo Random Number generator.  I believe you chose it, aside from what was found, is that its much "faster" then perlin or simplex.  However, it has a limited output appearance (It gives similiar/same look)  which is fine, depending on what your goal is.
Not sure what you mean? My understanding of 'perlin noise' is a PRNG from which values are mixed and smoothed at various amplitudes and frequencies to produce an interesting, repeatable result. Sure you can use the output of perlin noise as the input for more perlin noise, but there has to be a PRNG in there somewhere!

People make games and games make people
Offline endolf

JGO Coder


Medals: 7


Current project release date: sometime in 3003


« Reply #19 - Posted 2011-04-10 22:48:30 »

With simplex noise I set the permutations using a bitset and Random, I can seed the random number so that the same permutation would be set. e.g. set the random seed using the hash of the level name. That way, every client will generate the same thing for that level, and generate something totally different for the next.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
BitSet set = new BitSet(256);
set.set(0, 256, true);
int[] perm = new int[256];

for(int i=0;i<256;i++) {
   int nextGeneratedIndex = (int) (randomNumberGenerator.nextFloat()*256);
   int nextIndex = set.nextSetBit(nextGeneratedIndex);
   if(nextIndex == -1) {
      nextIndex = set.nextSetBit(0);
   }
   perm[i] = nextIndex;
   set.flip(nextIndex);
}


then just use perm as the permutations for your simplex noise.

Endolf

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

CogWheelz (18 views)
2014-07-30 21:08:39

Riven (26 views)
2014-07-29 18:09:19

Riven (15 views)
2014-07-29 18:08:52

Dwinin (13 views)
2014-07-29 10:59:34

E.R. Fleming (34 views)
2014-07-29 03:07:13

E.R. Fleming (12 views)
2014-07-29 03:06:25

pw (43 views)
2014-07-24 01:59:36

Riven (44 views)
2014-07-23 21:16:32

Riven (30 views)
2014-07-23 21:07:15

Riven (31 views)
2014-07-23 20:56:16
List of Learning Resources
by SilverTiger
2014-07-31 18:29:50

List of Learning Resources
by SilverTiger
2014-07-31 18:26:06

List of Learning Resources
by SilverTiger
2014-07-31 13:54:12

HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!