We’ve added Stefan’s benchmark’s (and Stefan) to the repository and included a number of suggestions and fixes from earlier in the thread. http://github.com/ashima/webgl-noise
The code in the Github repository provided by Ian has now been updated rather a lot, and I no longer recommend using my pre-packaged zip archives posted above. They still work, but I will not be updating them on a regular basis. Please use the Github repo to get the latest versions of the shaders and the benchmarking application.
And for those of you wondering, yes, there is a write-up coming. We’re working on it right now. In the meantime, feel free to ask any questions here.
The invSqrt taylor approximation uses the value 0.83666002653408, which is the square root of 0.7, shouldn’t this be the inverse root of 0.7, i.e. 1.195228609 ?
Yes, of course. Good catch, thanks! It has only a minor effect
on the final result, but it does make a difference. This change
will be committed to the repository as soon as I have
determined the corresponding scaling of the final values.
Your benchmark is 25% lower than mine on the same hardware and software (MacBook Pro, GF9400M, MacOS X, 1280x800 fullscreen). Did you run the demo on a single screen? Mirroring, or just having a second display active, tends to slow down the display subsystem rather a lot on MacOS X. An earlier post on page 4 of this thread contains my results.
Yes, I ran it on a single screen, same resolution, same gfx, OS: MacOSX Snow Leopard, but my Macbook is not the “Pro” version. Perhaps there are slight differences in the CPU speed. I will try again assuring that there aren’t any background application that could slow down the system.
For some reason, that “Fragment shader compile error:” shows up on many platforms, although the error message you get when you ask what went wrong is an empty string. On some systems I have tried, the “error” reported is even “Shader successfully compiled”, so I think the notion of when to signal an error is kind of hazy to many GLSL compilers.
I have not read the recent source code of the program and this is only a suggestion.But the program should not rely for shader compile failure on the info log. But it should rely on the compile status.
His permutation function drops 0 on 0. Otherwise it is good.
That 0->0 mapping is not a problem. It is perfectly alright for a permutation to have one or even several fixed points that map to themselves, as long as they do not appear in a too regular pattern.
The permutation is a permutation polynomial: permute(x) is computed as (34*x^2 + x) mod 289.
This is one of the two neat and original ideas in Ian’s implementation. (The other one is the clever generation of gradients.)
You can read about permutation polynomials on Wikipedia.
It is not a new idea in mathematics, it is just new for this application. A proper journal article on this noise implementation is on its way, but please have patience.
The github repository has now been updated with some slight speedups, code cleanups and classic Perlin noise in regular and periodic versions.
2D simplex noise is now only about 20 mult and add operations (including five dot operations), one division, three mod, two floor and one each of step, max, fract and abs.
I get 1,5 billion 2D noise samples per second on my relatively measly Nvidia GTX260. An ATI HD5870 spits out 5 billion samples per second.
The 2D simplex noise was just optimized some more. I replaced a division with a multiplication and removed one multiplication and one addition by introducing two more constants. The speedup I see on my system (ATI HD4850) is about 5%.
The level of hand feeding you need to do to optimize GLSL code reminds me of C compilers from the early 1990’s.
I’m curious if this was your general GLSL experience with ATI, NVidia, and Intel drivers, or just regarding ATI drivers in particular.
With NVidia, I’ve been amazed at how much complexity/infrastructure you can stack on top, but yet how effectively it aggressively throws away things and transforms the code into something very efficient.