2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

toneburst's picture

I finally got it working. It's not fast, but it's kinda fun... Here's a clip. I'll post the QTZ a bit later, if anyone's interested.

To get it to work on my 1st-gen MacBook Pro, I ended up using texture fetches in the vertex shader, to lookup values in a 2D permutation table. After all the bad experiences I've had in the past with trying to use textures in the VS, I wasn't expecting it to work, but it seems to be fine.

Shame it's so slow though. There must be a faster way of doing this...

The lighting used is a basic Phong directional model, incidentally, though now normal-calculation is sorted, lots of other lighting effects could be used.

a|x

toneburst's picture
Now also with 3D variant, file attached

OK, here's the composition. 2D and 3D variants. It's slowwwwwww (especially the 3d noise), but fun.

On machines with pokier GPUs than my MavBook Pro's X1600/256MB it should run at a reasonably framerate. Probably a non-starter on GMA-equipped machines though (may be worth a try- I'd be interested to know if it actually does run, or just crashes like my last attempt).

a|x

PreviewAttachmentSize
tb_VTF_vBomb_0.5.qtz172.94 KB

cybero's picture
Re: Now also with 3D variant, file attached

Swift.

psonice's picture
Re: Now also with 3D variant, file attached

Very nice. Works great here - 60fps at fairly high res (1200 x something), with max mesh res + 3d noise :) (I'm on an imac with radeon 2400)

waxtastic's picture
Re: Now also with 3D variant, file attached

My laptop is beind repaired right now, but tested it on a new iMac with NVIDIA GeForce 9400.

Runs very smoothly. 60 fps most of the time. Only slows down to 30fps with 3D and Max Resolution settings.

gtoledo3's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

How cool, I bet it can look really freaky inside of a logic op.

I am reminded of the pottery scene in "Ghosts".

waxtastic's picture
Re: Now also with 3D variant, file attached

My laptop is beind repaired right now, but tested it on a new iMac with NVIDIA GeForce 9400.

Runs very smoothly. 60 fps most of the time. Only slows down to 30fps with 3D and Max Resolution settings.

toneburst's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

gtoledo3 wrote:
How cool, I bet it can look really freaky inside of a logic op.

I am reminded of the pottery scene in "Ghosts".

ewww....

gtoledo3's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

I knew you would love that :o)

Can we have a couple md2's sitting down, spooning, with this blob in front?

I always had a feeling that this whole Kineme thing was just a ruse to recreate Patrick Swayze movies inside of QC.

Lest you think I'm busting your chops, this is totally awesome looking.

toneburst's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Cheers!

erm.. I think...

Could you guys test this other version for me, too, if you have a moment, just to see if it's faster/slower than the original one.

a|x

PreviewAttachmentSize
tb_GLSLBuiltinNoise_vBomb_0.5.qtz19.05 KB

toneburst's picture
Re: Now also with 3D variant, file attached

Cool!

Time for my MacBook Pro to be retired, I think.

a|x

psonice's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Slower and broken :D

I get ~30fps, with a smaller window than before. And it's showing a black screen.

cybero's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

20 -21 fps rate on this one - slower.

gtoledo3's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

The first one looks like a bunch of jaggy splinters waving around. I get that with psonice's old displacement stuff as well. I don't think that's what you were going for?

The second one looks correct basically, and works, but there is a very little "hole" in the surface in the middle that looks black. If I look inside of that hole, it looks like an extremely miniature version of the entire surface... needle tip size type of thing.

usefuldesign.au's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Have to say well done tb on this. Opens a whole new dimension to qtz ideas. I'm afraid of GLSL. Now I'm really afraid I gonna get left in the dust with this kind of stuff. Congrats on your perseverance.

toneburst's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Weird... sounds like the first one is broken on your hardware, then, and it's not running in software, by the sound of it.

The 2nd one sounds like it's running OK. The hole I get also. Didn't realise there was something inside there, though...

a|x

toneburst's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Wow.. a shader minefield....

Right: example one uses Vertex Texture Fetches, which, as a few of us have already discovered, is flaky as f*ck (though may have been fixed for some people, on some hardware). However, on this occasion, it's looking-up a static image, which works fine for me. I say 'fine' though- I mean it works. BUT, it's dropping-back to software rendering. How do I know? Because when I switch QC to Software GL, it runs at exactly the same speed, ergo, it was doing software GL all the time. Pants.

The second example uses the builtin GLSL noise1() function, which has been part of the GLSL spec from the beginning, but isn't actually implemented on most GPUs, as far as I can tell. Sooo.... guess what- it's falling back to software rendering again, on my machine, at least. It looks like using noise1() is actually breaking the composition completely on some machines, while VTF is breaking it on others.

I'd be really interested in knowing if either/neither/both run on your respective machines actually on the GPU. I suppose ultimately, if you're getting a good framerate, it doesn't really matter if it's running on the CPU or the GPU, but I'd still like to know.

If it's not too much of a hassle, could you guys possibly test on your machines, and report back the following info:

Mac Model GPU/VRAM

version 1 (VTF) Works in Hardware GL mode? FPS in Hardware GL mode Works in Software GL mode? FPS in Software GL mode

version 2 (builtin GLSL noise1) Works in Hardware GL mode? FPS in Hardware GL mode Works in Software GL mode? FPS in Software GL mode

To drop QC Editor into Software GL mode, hold down Alt/Option while selecting Preferences, then tick Software GL in the Editor tab.

Cheers,

a|x

toneburst's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

God no.. that would be terrrible.... ;) a|x

SteveElbows's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Lovely composition, thanks for sharing.

2 year old Macbook Pro, 2.4Ghz, GeForce 8600M GT 256MB:

3D noise, highest grid res, 1280x720 composition resolution. First one runs at around 80fps with not too much CPU used, so I assume its using the GPU. Second one runs at 5.4fps and uses a lot of CPU, I assume its using software.

SteveElbows's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

With software mode explicitly set I get 2.5fps for the first one and 4.6 for the second.

All of them look as expected, although I get a very small black circle in the middle of the screen, which moves out of view if I use the trackball.

gtoledo3's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

The only time that QC will use only the "software renderer" is if you choose so in your options.

Otherwise... you are always using the GPU as well as the CPU.

cybero's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Actually, if you jig with the displacement and such on either file you'll get a dark "Watchmen" looking blob - dark circle, containing a miniature something or another. I thought it was deliberate. Looked quite cool drifting around over the surface as I got it to jig to audio data.

Really good looking blob - sphere though.

Swift and Smooth

:-)

cybero's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

PPC Dual G5 1.8 GHz/nVidia GeForce FX 5200 64MB

version 1 (VTF) Works in Hardware GL mode? Y FPS in Hardware GL mode 29 -30 Works in Software GL mode? Y FPS in Software GL mode 14 -15

version 2 (Built In GLSL Noise) Works in Hardware GL mode? Y FPS in Hardware GL mode 1 29 -30 Works in Software GL mode? Y FPS in Software GL mode 14 -15

iMac 2.66 GHz / nVidia GeForce 9400 256 MB

version 1 (VTF) Works in Hardware GL mode? Y FPS in Hardware GL mode 60 Works in Software GL mode? Y FPS in Software GL mode 30

version 2 (Built In GLSL Noise) Works in Hardware GL mode? Y FPS in Hardware GL mode 1 29 -30 Works in Software GL mode? Y FPS in Software GL mode 14 -15

Interesting to see that the in built GLSL is a] slower than your ingenious VTF version and b] really consistent across platform and chipset and generation of Video Card, despite any added oomph on the VRAM, CPU or GPU front.

Brilliant work, toneburst.

SteveElbows's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Im vaguely surprised by the consistency of your numbers, if you run the comp at a higher resolution and play around with the composition settings such as grid size, do you get more variation?

toneburst's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

gtoledo3 wrote:
The only time that QC will use only the "software renderer" is if you choose so in your options.

Otherwise... you are always using the GPU as well as the CPU.

Not true, George. If the GPU chokes on a particular shader, it silently drops back to software rendering. The driver is a almost a 'black box though'- you don't necessarily know when it's running a particular shader on the GPU or the CPU. Two things that seem to guarantee software GL on my MBP/X1600 is noise() and textures in the vertex shader.

a|x

toneburst's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

OK, this is all a bit confusing, but it looks as though noise1() isn't implemented in hardware on any of your machines, except maybe cybero's iMac.

Version 1 seems to run faster on all your machines, though, unlike on mine.

Looks like my initial instinct to not bother using GLSL's builtin noise1() function was correct, so, happily, I don't feel like I've wasted all those hours, afterall.

The hole in the middle is a bit annoying, isn't it? Wish I could get rid of that...

Thanks for your work, guys! I feel kinda vindicated :)

a|x

cwright's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

I know it's semantics, but his (george's) statement was:

"The only time that QC will use only the "software renderer"..."

(emphasis mine)

which, in a literal sense, could mean that unless you have the software-only renderer enabled, you'll have some combination of cpu/gpu rendering going on. The exact mix is difficult to determine, of course, and is, as you note, driver dependent.

So I don't know that George was wrong, just brief. (and, to be honest, who wants to be entirely verbose when it comes to gpu drivers? even the vendors themselves can't get it right all of the time...) ;)

toneburst's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Good point, cwright. I guess it could be executing the VS on the CPU, and the FS on the graphics hardware. Or the other way around.

Sorry to have been a bit harsh there, George.

a|x

psonice's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

The vertex shader will indeed fall back to hardware while the rest runs on the GPU. Best way to test it I've found: write a really simple + fast shader that uses a large animated (this is critical) texture. Put a rotating cube in a large render in image for a quick + easy source. Set different textures (also essential) for the vertex and fragment shaders.

In theory, that should run very fast.. if it doesn't, some/all of it is running in software. It should still be fast in software, but bus transfers of large images per frame really kill it. To figure out which parts are running in software, just play with the image size for each shader - smaller image sizes will make it much faster if it's running in software, but won't affect it much if it's running in hardware.

The hole: I'm guessing it's to do with how the QC sphere is built, combined with how you're doing your normals. QC doesn't use a normal tesselated sphere (i.e. made of equal sized triangles), it seems to use a grid wrapped into a sphere shape. Not very efficient - you get tons of tiny polys at the poles, and big obvious ones at the equator. But anyway, if that's the case, then the polys at the poles are a 'special case': they're quads, but have a triangular shape, so some triangles have 2 vertices in the same position. If you're getting the normal by working out the neighbouring vertex position, and that vertex is in the same place as your current one, that will cause some funkiness.

toneburst's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Good tests, Chris.

Re: the hole: I'm actually creating the base sphere from a flat GLSL grid in the shader itself, so essentially, the entire vertex noise process is a parametric UV equation. That's now I'm able to work out the normals, by running the whole process

grid > sphere > distorted sphere

three times. Once for the actual vertex position, then again with an x-axis offset to the initial mesh coordinates, then again with an offset on the y-axis. Then you take the cross-product of the distances between the distorted vertex position and the result of the X/Y neighbours. Sounds like you know all this already, Chris, but an explanation might be useful for some of the other guys.

It's a brute-force method really, but I don't know how to do it any other way.

The hole is because the sphere gets displaced along the normals the vertices would have if they actually formed a sphere- ie along the continuation of a line from the centre of the mesh to the vertex. So, all the vertices essentially diverge from each other, and where they should meet at the top and bottom, they now no longer quite do at one end, and overlap a bit at the other. At least, I think that's what's going on.

What I'd really like to do is to calculate the normal without having to start from a flat mesh- so I'd eliminate the need for the sphere function, and start from a sphere mesh at the beginning. Dunno how I'd do that though.... I did think about using spherical coordinates rather than cartesian ones to work out the positions of the neighbours, but then it struck me that the neighbours would get much closer together at the top and bottom of the sphere, but maybe there's a way around that. To get this to work though, might actually turn out to be as expensive as doing it the current way though...

a|x

cybero's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Quote:
if you run the comp at a higher resolution and play around with the composition settings such as grid size, do you get more variation?

Yes one might think Bigger is *Slower

Actually

No Difference {At All}

LOL, eh. Or perhaps scratch one's head, or simply admire the way that toneburst's coding has dovetailed so neatly by and large with the presumably consistently performing graphics drivers and graphical frameworks either on the slower PPC - or the 2*faster Intel Mac.

Could bore us all with the screen shots, but believe you me, the figures presented would not have differed one iota, not so far as I've been able to stretch & resize. So much for screen resolution.

However, if I adjust the mesh resolution, then the VTF retains FPS consistently through out all Mesh resolutions at any screen resolution, whilst the GLSL built in really does depreciate FPS wise at higher resolutions.

Max 200200 - 7 FPS High 100100 - 16 FPS Medium 7575 - 30 FPS Low 5050 - 60 FPS

Even so, the FPS rate is held consistently. So I guess what this means is that the inbuilt Noise GLSL could be improved upon.

Trophy to toneburst in any case ; thanks for the very interesting code tb.

Thanks Steve - you got me looking again at something that performed so well for me I didn't even think to look just a little deeper into still;apologies for slowish response, I've been busy sorting out my new network [Airport Extreme - Steady Green]

gtoledo3's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

lol... I haven't read whatever you said yet, but what Chris is saying is exactly what I meant... "only" was a very operative word.

Ok, I'll go look at the flame fest :o)

gtoledo3's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Ok, looked back on your post... yeah, in regular render environment, it is a mixed bag, for sure. We are co-correct.

There are so many different gpu's out there, that I don't tend to think about "what is gpu vs cpu", because it can be wildly different from model to model. I tend to think about "what isn't going to work on a particular model because of a bug", or what do I have to do differently. I always think of software only rendering mode as a tool for seeing if something is a hardware issue, or an actual QC bug.

(on a side note, I need about a half day to sit down and file QC bugs, because I've seen about a half dozen doozies... really disturbing lack of compatibility in compositions between models- having to do things like range input splitters on the new mac mini's, albeit in very obscure scenarios- and not having to on towers... movie player not resetting current position when loaded with new movie... input publishing problems with certain protocols... etc etc).

gtoledo3's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Ooh, I am in a mega rush to do a bunch compositions and came here for a quick mental refresh... but I will check them out with software only mode and report back. I'll do screenshots as well. I know how it sucks when you can't get feedback about compatibility, and it's always on the coolest stuff...

gtoledo3's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

I seem to remember you mentioning to me that I should take this one on a long while ago :) ... cause it's a pain in the butt huh? I want to take a look at that hole if I get a chance, it is vexing.

cybero's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Quote:
noise1() isn't implemented in hardware on any of your machines, except maybe cybero's iMac.

I can't believe I'm the only one running an nVidia 9400 ! Apple seem to put that into almost everything nowadays.

Version 1 runs slower on your MBPro? Strange hardware dependent result toneburst.

I like that hole, it slips around like a roscharch blob, I wonder if that sort of effect can't be elicited upon that resultant dot?

toneburst's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Oh, was it you who was trying to get the original apple Vertex Noise sample to work with the Environment Map lighting shader?

I was trying to remember...

Well, here's a working version of what you had in mind, I think. It's basically just the EnvMap lighting applied to the Perlin noise shader above. I've also moved the calculations of the texture coordinates for the envmap lookup from the vertex shader to the fragment shader, to make it a bit smoother. It still looks a bit rough, but that's partly down to the way the texture coords are stretched and pinched by the sphere function (as psonice mentioned earlier).

a|x

PreviewAttachmentSize
tb_VTF_vBomb_0.5_EnvMap.qtz176.21 KB

toneburst's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

cybero wrote:
Version 1 runs slower on your MBPro?

Yeah, it's a weird one. It runs about twice the speed on my machine (29-30fps, as opposed to 12-25 for version 1), and also recompiles more quickly, when you edit the code. Maybe the compiler is having issues with the length of the vertex shader code. Having said that, take out all the comments, and it's not really all that long.

Quote:
I like that hole, it slips around like a roscharch blob, I wonder if that sort of effect can't be elicited upon that resultant dot?

I'd like the option to get rid of it, though. Actually, the hole is less annoying than the the cat's arse on the other side ;)

a|x

gtoledo3's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

I wanted to post an example of that thing with the logic op that you asked me about on vimeo, because the whole blobby aspect is bringing it to mind... I think I incorporated some torus shapes with the vertex shader, which to me looks like a "Dali" version of a donut. I love wiggly vertex! I've had so many crashes with vertex shaders, especially when trying to do abnormal stuff.

This is my go to setup when I want something similar. No controls setup, etc, etc., this was 3 min job...

I like the whole concept of distorting by feeding a texture, or other things though... I am way in favor of advents like this. I'm still dying to use the last kineme3D update with that feature more. I had some Terminator liquid metal stuff going in no time.

PreviewAttachmentSize
old faithful.qtz4.83 KB

gtoledo3's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Oh, how interesting... I'll take a look at it in a bit. I did get it going, but it's been so long I don't remember the exact setup. I'll be curious to see what you did with this. It seems like I did something with the texture coordinates that was totally off the cuff but that looked good. Or maybe I made spherical textures... I'm thinking that's what I did...

offonoll's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

Hi! I am also interested on get rid of the hole poles. Reading your last posts, I have nVidia 9400 but now I use NVIDIA GeForce 9600M GT 512MB and it goes very smooth, no problems with speed what so ever.

Regarding the holes, I have been touching the code a bit and, in my opinion, is an edge texture of the u and v. the holes aren't holes at all, they are black points, to see that, you need to prescale Y and have 2 light to see the color render on the rexture. with only one color its difficuld to realise what's going on. adding 0.04 to u :

////////////////////////////////
// Calculate Position, Normal //
////////////////////////////////
 
const float grid = 0.01;   // Grid offset for normal-estimation
varying vec3 norm;         // Normal
 
vec4 posNorm(in float u, in float v) {
   // Vertex position
   vec4 vPosition = perlinSphere(u, v);
   // Estimate normal by 'neighbour' technique
   // with thanks to tonfilm
   vec3 tangent = (perlinSphere(u +.04+ grid, v) - vPosition).xyz;
   vec3 bitangent = (perlinSphere(u +.04, v + grid) - vPosition).xyz;
   norm = gl_NormalMatrix * normalize(cross(tangent, bitangent));
   // Return vertex position
   return vPosition;
}

these two pictures attached shows you that the first and last vertex aren't colorized. The black hole gets the color from the ambient.

You could set big amount of u points to make a small 'hole' or it may be a way to fix code.

PreviewAttachmentSize
hole1.png
hole1.png46.61 KB
hole2.png
hole2.png118.9 KB

toneburst's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

psonice wrote:
The hole: I'm guessing it's to do with how the QC sphere is built, combined with how you're doing your normals. QC doesn't use a normal tesselated sphere (i.e. made of equal sized triangles), it seems to use a grid wrapped into a sphere shape. Not very efficient - you get tons of tiny polys at the poles, and big obvious ones at the equator. But anyway, if that's the case, then the polys at the poles are a 'special case': they're quads, but have a triangular shape, so some triangles have 2 vertices in the same position.

Oh, I see what you mean now. Inigo Quilez has a nice little tutorial on his site about creating a 'patched sphere' ( http://iquilezles.org/www/articles/patchedsphere/patchedsphere.htm ) by normalizing the vertices of a cube. You need a cube with a grid of vertices for each face though, rather than the standard QC primitive, that has only 6 verts, one at each corner. That being the case, you may as well just make a sphere like his example in a 3D app, and import it via Kineme3D or the new Mesh Importer in QC4.

The problem, in this case, then becomes calculating the normals. I guess you'd have to use spherical coordinates to work out neighbouring positions on the surface of the sphere, then apply the Perlin function, get the cross-product, etc. I seem to remember trying this though, and it not working. I'll have to give it another go sometime though.

Quote:
If you're getting the normal by working out the neighbouring vertex position, and that vertex is in the same place as your current one, that will cause some funkiness.

Ah, now I see what you mean. That's probably what's going on, in fact.

a|x

gtoledo3's picture
Re: 2D Perlin Noise In a GLSL Vertex Shader, With Lighting!

oooh, A cube! Of course! Thanks tb.