You’re forgetting the multiply before hand.
which multiply? the multiply of all the layers?
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?
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.
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.
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.
[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 < 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.]
Current tutorial bits look reasonable to me for understandability.
Animated flames! (Maybe a little cheesy, but still! ;D)
www.hexara.com/SimplexFlames.html
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.
http://hexara.com/flamesApplet.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?
You might want to look at “flow noise”…based on simplex…let me know if you can’t find a reference.
@Roquen - “flow noise”
Very intriguing! But I’m having trouble nailing down exactly what it is. I’ve found a few references, and a name (Fabrice Neyret) but not an actual demo or visual description, or even a very understandable written explanation.
Do you have a link or two to share?
After getting past the “sound of blood in your ears” definitions–I was thinking in terms of particle systems and the flow of the particles being modulated by noise. That could be a good way to do flames. In the flames code I wrote, there is a flow in that there is continuous translation to create the upward motions, as well as Z translation.
I’ve not dealt with shaders yet, or other 3D graphics elements. There is so much to learn…
It came out at SIGGRAPH at the same time as simplex noise and it was Perlin as well.
http://www-evasion.imag.fr/~Fabrice.Neyret/flownoise/index.gb.html
http://webstaff.itn.liu.se/~stegu/aqsis/flownoisedemo/
GLSL code from this new book: https://github.com/OpenGLInsights/OpenGLInsightsCode
Based on the type of things flow noise can apparently be used for, I wonder why I hadn’t heard of it before…
Hard question. I’ve zero personal experience with flow noise. Note that simplex noise really isn’t talked about much either, but you wouldn’t get the impression from this forum…likewise cell noise is used quite a bit and is hardly ever talked about. Probably part of the issue is that very few people are interested in faking fluid flow with noise. But (assuming it can create reasonable results) it seems like to should be a good candidate at least for (very) slow moving liquids…like gas planet “surfaces”, rocks, etc. etc.
I just found the following, a pretty good explanation for Cell Noise.
http://carljohanrosen.com/processing/
There is code and theory and lots of examples, including animations running via Java.
Very cool!
+++++++++
The “Flow Noise” is really interesting, but I can see a couple reasons why it might not be used much.
For example, it requires rewriting the noise function so that the gradient orientations are continually rotating. That is an “order of magnitude” increase in complication for someone who is simply using a function in a black-box fashion.
But it does seem like this technique could be the one to use if one wants to implement some sort of whirlpool-like turbulence visually.
So, tracing through these various links, including Roquens simplex implementation (http://www.java-gaming.org/topics/simplex-noise-3d/23962/view.html) I’m seeing that we have an OGL implementation?
I need to take a closer look at these libraries.
I would change some little stuff to your code to improve speed.
- Im sure raster.setPixel(x, y, pixel); is really slow compared to direct acces of the pixels
- I dont see why you split your color into bytes, just use ints
Improved code:
//Make sure you fill these variables:
public void init(BufferedImage img, Color start, Color end){
//Load raster of image
int[] raster = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
//Create color map
colorMap = new int[k];
for(int k = 0; k < 256; k++){
colorMap[k] = TweenColor(start.hashCode(), end.hashCode(), k);
}
}
//Credits to Dzzd (fast tween color)
public static int TweenColor(int c1, int c2, int a){
return ((((c1&0xFF00FF)*(256-a) + (c2&0xFF00FF)*a) &0xFF00FF00) | (((c1&0x00FF00)*(256-a) + (c2&0x00FF00)*a ) &0x00FF0000)) >>>8;
}
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;
else if (nSum < 0) nSum = 0;
raster[x + y*width] = colorMap[nSum];
}
}
}
Thanks for the suggestion Robin!
I just posted an update which uses your suggestion for coding the color as a single int, when using the color mapping functions. When using the mapping method, the program now uses image.setRGB(x, y, colorInt), and dispenses with the use of the raster.
I think I’ll keep the slow, but clear, raster.setPixel(x, y, pixel) for first couple tutorial sections.
I also wanted to acknowledge your suggestion and demonstration on how to post directly to the image data (which you made in a personal message, thanks!) and will test that out with my animated flames graphic, and probably include it if the tutorial gets into animation.
Really great that you are willing to look at the code and contribute! Thank you very much.
Testing: I get no pickup in processing speed using integers with all four colors in my color map vs using a pixel array. In fact it tested out to be a little slower!
In other words, using raster.setPixel(x, y, pixel[]), seems minutely better than image.setRGB(x, y, colorInt).
Go figure.
However, there is a significant pickup when using the following plan:
- copy the image data to an array
- write directly to that array
- copy the array back into the image.
For this, am using raster.getDataElements() and .setDataElements().
There is also a big difference going from a 2D simplex call to a 3D call.
Or you just could use this super fast array (a):
int[] raster = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
The raster is an pointer, what means, when you change any value, this will immediately affect the image.
Every int is an color like the setRGB method.
I have told you this is much faster, why dont you give it a try :).
If you’re motivated I’d be curious how fast my 3D version compares with whatever you’re using.