Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (686)
Games in Android Showcase (198)
games submitted by our members
Games in WIP (758)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
    Home     Help   Search   Login   Register   
Pages: [1] 2 3
  ignore  |  Print  
  Simplex noise, experiments towards procedural generation  (Read 36136 times)
0 Members and 1 Guest are viewing this topic.
Online philfrei
« Posted 2012-08-23 23:07:04 »

[EDIT April 9, 2013
will post GitHub url here [/url]]
original post follows

Not sure where to post this. I'm selecting "Game Design" as it is related to designing graphics (possibly animated) using Procedural Noise techniques.

I can see where there are a LOT of texture editors already out there, as well as Perlin & Simplex noise source generators. This post is more about learning about ways to combine noise "channels", to have a "hands on" way to see what happens if I poke something this way or that.

As a consequence, this is very much "In Progress" and the Applet is next to useless due to trying to cram too much on the screen. No way yet to save or load files or generate images. Can only dabble and see what happens.

I'm taking as my "base octave" the value of x/width, where x is the number of the pixel, and width is the number of pixels in the display area. This gives a progression from 0 to 1. I've seen others that use an equation that instead gives -1 to 1  for their "base octave". To progress more quickly across the Simplex space, one multiplies the x value by a scaling factor.

I made a provision to put in arbitrary scalings factors, as well as translators (values added to the x * scale), and made a display TextField to show the resulting equation that I could use if I want to program the display results procedurally.

This screen shot is of a well known example of combining octaves where the colors span from blue to white. (It CAN to other colors.) The values are added together in a way that tapers geometrically. The result: standard fluffy clouds.

The return value from the Simplex function ranges from -1 to 1, so to use it with designating a color value, a transform is common. Very common is (val + 1)/2, which shifts and compresses the -1 to 1 results to 0 to 1. Another common way is to use an ABS function: "|val|". This operation seems to result in a more threadlike quality to the noise. In the example below, I select "|val|" on the second Simplex channel and flip the colors (via "<>" button between the RGB fields) so that the thread color is White.

As I said, I wanted to experiment with other ways to make textures, not necessarily at octaves. I allow ADD vs LERP in the way values are combined. With ADD there is a possibility of overflow & underflow. The "Prevent Overflow" puts in a MIN function to prevent the color value from exceeding 255. So there are some interesting clamping effects. The slider value with ADD is divided by 64, thus as long as the four channel volumes add up to less than 64, you are okay (unless you allow the "no transform" option and are sending in negative values, potentially causing underflow).

The program could use a way to Save & Load, and to generate jpgs or ani gifs (am thinking of putting some "rollers" on the translator sliders that continuously move). It could use a Color Picker and ways to automatically copy values from one channel to another or set octaves since they are so powerful a construct. It could use a much better use of space, maybe popping up the thing you are working on, while letting other aspects that don't have the focus stay smaller.

I want to maybe allow other panels in with other texture sources, as well as a way to explore using the Simplex to generate a value along a custom gradient (such as are used with "earth" colors to make topo maps), or the classic cloud demo on Perlin's lecture site. But I don't think I really want to invest a lot of time making yet another texture builder app. As I said, my main goal was just to get some "hands on" with noise textures which this code allows to a limited extent.

music and music apps:
Online Roquen
« Reply #1 - Posted 2012-08-24 08:22:21 »

Food for thought:

check box to 'lock' X and Y scale values to be the same.
rotation: currently by having different X and Y scale values you can get anisotropic (directional) results but only aligned to X or Y axis.
keeping single channel values until the end and the applying that to some look-up is very effective.
Offline endolf

JGO Coder

Medals: 7
Exp: 15 years

Current project release date: sometime in 3003

« Reply #2 - Posted 2012-08-24 12:37:23 »


Thanks for this, I wondered how to get whispy effects for gas clouds in darkvoid as well as the plain gas clouds already in there. Now I can play and see how the values effect things quickly, might have to have a play with the background generation again Smiley



Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline krasse
« Reply #3 - Posted 2012-08-24 13:30:35 »

When I went down the procedural texture route myself I learned a LOT by fooling around with Genetica

Online philfrei
« Reply #4 - Posted 2012-08-25 15:10:13 »

@Roquen -- Good suggestions. Thank you. I got busy again, hope to get back to project soon, to add these and some other ideas.

@endolf -- Yay!

@krasse -- Will check out. Thanks for the link.

music and music apps:
Offline keldon85

Senior Devvie

Medals: 1

« Reply #5 - Posted 2012-08-25 15:29:30 »

This is awesome ... it's almost like programming a synth patch Cheesy

Online philfrei
« Reply #6 - Posted 2012-08-30 09:54:49 »

@keldon -- Maybe this is not surprising given how many hours I spent with the DX7 & FM7 (my FM synths, hardware & software)!

I programmed the ability to make a reference gradient, with 8 color points (7 RGB gradients between them). But I am realizing I totally messed up the way the channels are being added together. I'm taking each channel and getting a color, then adding or lerping the color values. But I think for this effect, one has to add the numbers together first, before doing a lookup on the color bar at the end of the process.  Tongue

Well, this is why it is a hands-on learning project. Hope to have the next iteration within a few days.

music and music apps:
Online Roquen
« Reply #7 - Posted 2012-08-30 11:17:24 »

On the whole, mapping at the end seems to be the more useful thing to do (but I've very rusty at all this stuff).  Also modulation would be handy.
Online philfrei
« Reply #8 - Posted 2012-08-31 09:36:08 »

I've gone ahead and posted some modifications, even though I didn't address the main issue yet: mapping to the color bar once at the end, after summing the channels.

I did add a "lock" checkbox to keep X & Y at the same ratio when scaling. (Thank you, Roquen for the suggestion.)

Slider for scaling goes up to 128 now, instead of just 64. But you can enter higher numbers in the text field, or by locking the slider at an unbalanced ratio and pushing the lower slider up to the max. Kind of cool, the way threadlike things can appear at higher settings.

Added a tool for making color bars with gradients. Click on the gradient bar at the top of the channel and you get a panel of color bars to choose from for that channel. The popup panel matches the panel in the lower right corner.

Click on a color bar in the lower right corner, then you get the ability to edit that color bar. Click on the gradient bar at the top of the edit area to get a color chooser to add a gradient point at that location (up to 8 points or 7 gradients allowed). Or click on the color pad on the row of gradient points to bring up the color chooser. Field on left is location on the bar (from 0 to 255 -- the bar is 256 pixels wide). Three fields on the right are R, G, B.

It is possible to make a gradient to match topo-map colors without too much trouble. I was able to recreate the one in the AngryOctapus Simplex tutorial (that he made via GIMP and imported) pretty easily. But as I wrote earlier, the attempt to display this was a mess due to the way I'm mis-handling the channels.

Am still pondering how to do the GUI layout to allow EITHER the current form of merging channels, each mapped individually, vs. doing the more correct thing of adding the noise (or adding it to a sin function or gradient function) prior to the mapping at the end. Maybe I should just do it right and let go of the current method, but I really like some of the textures I've been able to build this way, and want to keep this as an option. (Would like to figure out how to place a couple more channels, too.)

Re: rotation -- yes, an important point. I came across this problem with the Night Sky Procedural. I had to figure out how to rotate the BufferedImage created via the SimplexNoise (the "galactic cloud"). And, this problem led to the work on the image rotation tool I posted earlier. (Still want to go back and clean that up!) But I think as far as this little app is concerned, it is moot until the functionality of saving an actual graphic is added.

music and music apps:
Online Roquen
« Reply #9 - Posted 2012-08-31 09:54:48 »

Another thing about rotation is that defects will show up based on the underlying structure (particularity if the hashing function is poor)..and most notably if you're doing some turbulence (sums of |noise(c)|).  And any easy way to correct this is to insure that the structures of the various octaves are not aligned via rotation (again..just more food for thought)  (I just modified the hash function in my simplex noise example code partially for this reason).
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online philfrei
« Reply #10 - Posted 2012-09-04 23:14:57 »

Quote my simplex noise example code...
@Roquen -- I'm very curious about the example code you mention. Do you have a link to share? Did you make an app or tool of some sort? Are you using textures in your games?

I'm not entirely clear what is meant by "defects" and why they would be more apparent with rotation. Can you explain what you mean?

I'm happy to say that I got the proper "summation" noise effects working last night. Was able to get a pretty close repeat of the 'planet surface' example by AngryOctapus (cited earlier) and a night "twilight clouds" effect (gradient from a sort of rosy/salmon to grey to blue instead of white to blue).

But the app has gotten really laggy. I want to try and improve the response a bit before I post the latest version. Also, I want the new version to be able to do either method of combining textures and have some coding to do before that happens.[update posted 9/4/12]

This shows the correct use of summation for a twilight cloud effect. Summation of the four channels is done prior to consulting the color map.

The next image (NOT CORRECT) combines the same four Simplexes as the above, but does the math using the color values, and brings up intermediate colors, the purples.

Another misadventure: trying to make an Earth Map, but blending AFTER color mapping rather than before. It just overlays the four "octaves".

Better, with maybe a better ColorMap, too:

First step towards a plasma fireball? (Some shaping and masking with the alpha channel will be an important step. Maybe animation via translating on the z-axis, too.)

Hey, if its "procedural," it's coding, not goofing off, right? right?  Roll Eyes

music and music apps:
Online philfrei
« Reply #11 - Posted 2012-09-05 06:12:18 »

Notes on updates, 9/4/12.

I have a two stage mixer in the lower left, and I acknowledge the non-intuitive design. Will ponder how to improve it.

Main thing, if two channels use the same Color Map in the same way (ADD/LERP/SIN), then they will be merged into the same "second stage" mixing line.

Second stage rows can be added together or averaged together (lerped).

Of the first stage mixing options, I still haven't implemented the LERP & SIN options. For best results, try to get all the tracks that share a 2nd stage row to have their 1st stages add up to 64.  Tongue

The sliders on the top channels have become very laggy. Am pondering what to do about it. I suggest typing in values rather than sliding to them.

GUI design is hard.  Sad

music and music apps:
Online Roquen
« Reply #12 - Posted 2012-09-05 12:50:28 »

WRT: My code - just the example 3D simplex noise I'd put up here.  I'm not doing anything with was just a first pass before converting to Cg or GLSL...which I never got around to.

I'm not entirely clear what is meant by "defects" and why they would be more apparent with rotation. Can you explain what you mean?
The quality of the hash function will effect the quality of the random vectors.  And even if the hash is really good the code you're using will probably be using gradient noise style vectors like: (+/-X,0) , (0, +/Y), (+/-X,+/-Y) there are defects in the X, Y and along diagonals. These shouldn't be apparent unless they start to compound, so having octaves that are rotated with respect to each other will help to insure that they don't compound (as long has the rotations aren't multiples of pi/4).  Having said all of that, if you're not seeing any just doesn't matter.
Offline Sammyster

Senior Newbie

Medals: 1

« Reply #13 - Posted 2012-09-06 15:10:43 »

Really cool work you done here Philfrei, keep it up!  Smiley
Online philfrei
« Reply #14 - Posted 2012-09-08 04:00:22 »

Thank you Sammyster!

I posted some more progress. The lagginess was largely due to a rookie mistake: drawing parameter values from widgets from within the inner loops instead of having the widgets update a "model" and getting the values from the model.

I have a "striping" function working, but with no parameters, and it needs tuning in several regards (and for me to understand it better). I also have X-Gradient and Y-Gradient versions working, so one can use the noise in a more 1D fashion. To use it, though, the best settings for the lowest amplitude settings one can manage, otherwise the Noise functions max out the display.

I'm going to try and make some popup panels that have a palette of some of the most common usages, with explanatory text and have them automatically set up the GUI to get the effect.

The ColorBar/Gradient editor has improved a bit with a "negative" and a "flip" function. Also, it is possible to make a copy of a colorbar now, too. I am starting to get annoyed with the way RGB interpolation looks. Every end point sticks out as a saturation peak, I think, which works against smooth color transitions. For example: going from bright red (255, 0, 0) to bright green (0, 255, 0) -- the brightness and saturation drops precipitously for the intermediate yellow (128, 128, 0) when a bright yellow makes more sense (255, 255, 0) as the midpoint visually, it seems to me.

So, we've got HSBtoRGB and RGBtoHSB built in to Color methods--I plan to make an option to allow one to select one or the other when calculating the interpolations.

Also very much want to do a radial gradient (center out) and work in some "perspective" effects by allowing the amount of scaling to vary.

music and music apps:
Online philfrei
« Reply #15 - Posted 2012-09-19 22:15:03 »

[Edited multiple times--I think I'm done now.]
Continuing to work on this. New version has been posted and can be linked or downloaded (see top of first post).

There is a button on the bottom of the tool that says "Tutorial". Press it, and a menu of "basic textures" will come up. When you click on the graphic for the texture, it will load that texture into the tool. I will experiment to see if I can make the Tutorial screen not be modal.

I plan to add two to three more "basic usages" before calling this done and moving on to other things.

When you go into the tutorial, it gives you code that generates a BufferedImage that is the same as the graphic at the top of that page.

I thought putting the code first makes sense since this is written for Java coders. I try not to over-explain in the text but know I have a tendency to verbosity.

I guess my main goal here is to have something that is worthy of being linked to in our wiki section on Noise, as a demo of the basics of how to work with noise.

music and music apps:
Offline loom_weaver

JGO Coder

Medals: 17

« Reply #16 - Posted 2012-09-20 05:36:53 »

Pretty cool stuff!

I'm just starting to explore Perlin noise for my game.  I was able to get a simple version working but I definitely see the need for decent visualization in order to get the results I really want.  I was wondering what direction you wanted to take your current project.

Were you planning to open source it an any manner?  Would you be interested in any kind of collaborative effort?  I can offer interface improvements, testing on the Mac platform, and additions to the tutorial that would help other devs learning this stuff for the first time.
Online philfrei
« Reply #17 - Posted 2012-09-20 08:07:39 »

Pretty cool stuff!


I'm just starting to explore Perlin noise for my game.  I was able to get a simple version working but I definitely see the need for decent visualization in order to get the results I really want.  I was wondering what direction you wanted to take your current project.

Were you planning to open source it an any manner?

That seems like a definite possibility. I would love to discuss it more. There is a whole lot that could be done and would need to be done to make this into a real tool that other devs could make serious use of. Having more people involved could make it happen. However, I have absolutely NO experience with open source, and would need to learn from you and others how to go about setting that up.

Would you be interested in any kind of collaborative effort?  I can offer interface improvements, testing on the Mac platform, and additions to the tutorial that would help other devs learning this stuff for the first time.

Yes, I would be interested in collaboration. I would love to discuss this more with you.

music and music apps:
Online Roquen
« Reply #18 - Posted 2012-09-20 12:53:43 »

Only of interest for runtime creation - for rings, I've never noticed any defects introduced by just doing:

noiseValue = noiseValue - (int)noiseValue;
Offline matheus23

JGO Kernel

Medals: 138
Projects: 3

You think about my Avatar right now!

« Reply #19 - Posted 2012-09-20 17:08:19 »

Only of interest for runtime creation - for rings, I've never noticed any defects introduced by just doing:

noiseValue = noiseValue - (int)noiseValue;

I still don't get this...
(int) noiseValue will always be 0, because the input ranges from -1 to 1 (so actually -0.9999999999 to 0.999999 or something like that (even if that is not the case, it would be very unlikely that 1 or -1 existed)).

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Online Roquen
« Reply #20 - Posted 2012-09-20 18:21:33 »

You're forgetting the multiply before hand.
Offline matheus23

JGO Kernel

Medals: 138
Projects: 3

You think about my Avatar right now!

« Reply #21 - Posted 2012-09-20 19:28:21 »

You're forgetting the multiply before hand.
which multiply? the multiply of all the layers?

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Online Roquen
« Reply #22 - Posted 2012-09-20 19:42:35 »

Say you start with just a single sample per pixel gives range [-1,1].  Multiply by say 10, now on [-10,10].  Now do the subtract.  That make sense?
Online philfrei
« Reply #23 - Posted 2012-09-20 20:15:31 »

In my tutorial (there is a "Tree Rings" section) I came up with the following equation:

    noiseValue = noiseValue - Math.floor(noiseValue);

The int cast would be a more efficient option if the noise function returned only positive numbers. But using the above allows one to skip the normalization step. [Note: (int)-0.9 returns 0 not -1, but Math.floor(-0.9) returns -1]

However, the int cast is fine if you'd LIKE to see the wrap-around effect occurring in both directions, the direction depending on whether the return value is positive or negative.

The tutorial example code has a rings variable that is multiplied against a single noise function return value (multiplied against a number in the range [-1.0, 1.0] prior to chopping it back down into normalization range.

The Texture tool has an example where an overflow of the [-1.0, 1.0] range occurs due to adding together four noise call results. The example comes up in the tool when you click on the "Tree Rings" graphic.

But one can certainly sum together normalized noise function return values, and have the results range up into positive numbers sufficient to get a ring effect.

music and music apps:
Online Roquen
« Reply #24 - Posted 2012-09-21 06:47:29 »

It's true that using floor remaps to [0,1] where truncation remains on [-1,1].   I don't think this is a big deal esp. considering the performance difference.  Note that if this is happening at a final stage which converts to an int on [0,255], then all of this can be folded into (sticking to a single sample example):

float noise = (SimplexNoise.noise(sx, sy) + 1) * K;  // where K is 255 * number of rings (not ness. an integer BTW)
int t       = ((int)noise) & 0xFF;

And actually the "+1" isn't really needed.  Tons of ways all these bits-and-pieces can be tossed together.

On a complete different topic, If you're super motivated then reworking this using the spasi's DOPE tool (once released) would be crazy cool.
Online philfrei
« Reply #25 - Posted 2012-09-21 07:09:43 »

Yes, DOPE-ification is an intriguing possibility.

I went to a meetup talk this evening (just got back) and a fellow I met there was working on curricula for teaching game programming to jr high, high school kids and he sounded interested in seeing this thing. I warned him the interface was quite clunky. The younger the students, the more it seems to me it would be nice to have something like the DOPE methodology. (If I understand it right. Was having a little trouble getting my head around the particulars.)

Code generation was part of my original concept, but coding is so flexible and open to special cases for optimization, that I am losing interest in that aspect. Anything generated automatically would almost by definition be mediocre or sub-optimal. Also, my own understanding of what is going on is so much better now (after writing as much as I have) that I feel less personal need for the code generation, and am able to easily pop numbers from the tool into place. I'll keep putting code in the tutorials, though, as they are written.

music and music apps:
Online philfrei
« Reply #26 - Posted 2012-10-01 22:56:26 »

[Made a couple minor edits after finishing the rewrite of the "clouds" section.]

I've been doing a lot of writing for the tutorial. Part comes from reading some of the typical questions that come up, e.g., on StackOverflow.

Maybe there was a smarter way, but I am using JTextPanes for the tutorial, and presenting html-formatted text. This way, I can include graphics in the tutorial itself. What is a tutorial without some nice illustrations?

Anyone with editing/proofing suggestions? Ideas about presentation?

I think there are better initial values for those who first bring up the app. Source code is all included (links at top of this thread).

Been playing around with perspective, but haven't found a way to incorporate it into the tool yet. I may decide to forgo that as I really want to get back to working on audio tools, as well as using what I learned here to make some sand-dunes, marbling and other textures for Hexara.

[Edit Oct 2, 2012: Hate to keep bumping my project with every bug fix.
New or fixed:
 - problem with color bar editor not showing correct number of rows for the data fixed.
 - problems with code examples fixed:
    + forgot that we needed a copy of the SimplexNoise source for the dropin to work! So I exposed that.
    + html of > and < is screwy--had to add &lt; and the like to make the drop in code something one can copy from a browser.
    + rewrite of ColorBar code so that the "Terra Surface (ColorMap)" can be run from command line as well, but still more to do with that.
Lots of testing iterations. Sheesh.]

music and music apps:
Online Roquen
« Reply #27 - Posted 2012-10-03 11:21:48 »

Current tutorial bits look reasonable to me for understandability.
Online philfrei
« Reply #28 - Posted 2012-10-05 08:20:19 »

Animated flames! (Maybe a little cheesy, but still!  Grin)

Not part of the Simplex Visualizer (SiVi?) yet. I was working on the flames as a possible example of perturbing along the y-axis, and couldn't resist checking out what it might look like, animated.

I finished (but haven't proofed) the Color Map/Terran Earth Surface section of the tutorial. Thank you Roquen for looking over the first few sections!

Is it just expensive to recolor an entire graphic (iterating through every pixel) or maybe my method is not terribly efficient? For this small graphic, I can only get something like 45 redraws a second. That seems weak.

Source is packed with the jar.

I'm requesting a call an update method every 15 msec (via a Timer) that takes an existing WritableRaster and iterates through the graphic, making two Simplex calls (both 3D) per pixel. Graphic is 256x128.

   public void update()
      aniZ += aniZincr;
       for (int y = 0; y < height; y++)
          for (int x = 0; x < width; x++)
             noiseSum = 0;
             for (int i = 0; i < octaves; i++)
                noiseSum += SimplexNoise.noise(x * xScales[i],
                      y * yScales[i] + aniZ, aniZ)
                      * ( octaveAmplitudes[i] );
             nSum = (int)(noiseSum * 6 + y * verticalFactor);
                // clamp
                if (nSum > 255) nSum = 255;
               if (nSum < 0) nSum = 0;
               pixel[0] = colorMap[nSum][0];
               pixel[1] = colorMap[nSum][1];
               pixel[2] = colorMap[nSum][2];
               raster.setPixel(x, y, pixel);              

I've been putting off "Full-Screen Exclusive Mode API". Time to bite the bullet, perhaps?

music and music apps:
Online Roquen
« Reply #29 - Posted 2012-10-05 08:31:00 »

You might want to look at "flow noise"...based on simplex...let me know if you can't find a reference.
Pages: [1] 2 3
  ignore  |  Print  
You cannot reply to this message, because it is very, very old.

roseslayer (393 views)
2016-08-06 11:43:29

roseslayer (362 views)
2016-08-06 09:43:11

xTheGamerCodes (436 views)
2016-08-04 15:40:59

xTheGamerCodes (429 views)
2016-08-04 15:40:24

orrenravid (780 views)
2016-07-16 03:57:23

theagentd (855 views)
2016-07-11 14:28:54

Hydroque (953 views)
2016-07-06 05:56:57

Hydroque (981 views)
2016-07-03 08:52:54

GrandCastle (793 views)
2016-07-01 09:13:47

GrandCastle (634 views)
2016-07-01 09:09:45
Rendering resources
by Roquen
2016-08-08 05:55:21

Rendering resources
by Roquen
2016-08-08 05:52:42

Rendering resources
by Roquen
2016-08-08 05:50:38

Rendering resources
by Roquen
2016-08-08 05:49:53

Rendering resources
by Roquen
2016-08-08 05:32:39

Making a Dynamic Plugin System
by Hydroque
2016-06-25 00:13:25

Java Data structures
by BinaryMonkL
2016-06-13 21:22:09

Java Data structures
by BinaryMonkL
2016-06-13 21:20:42 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‑
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!