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.

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.

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

@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.

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

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 http://www.angryoctopus.co.nz/?p=11 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.

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).

@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.)

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

Quote

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)...so 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 defects...it just doesn't matter.

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.

[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.

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.

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.

Quote

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.

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)).

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

1

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.

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):

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.

[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.]

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.

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.

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