|
2D Perlin Noise In a GLSL Vertex Shader, With Lighting!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
|
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
Swift.
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)
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.
How cool, I bet it can look really freaky inside of a logic op.
I am reminded of the pottery scene in "Ghosts".
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.
ewww....
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.
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
Cool!
Time for my MacBook Pro to be retired, I think.
a|x
Slower and broken :D
I get ~30fps, with a smaller window than before. And it's showing a black screen.
20 -21 fps rate on this one - slower.
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.
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.
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
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
God no.. that would be terrrible.... ;) a|x
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.
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.
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.
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
:-)
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.
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?
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
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
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...) ;)
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
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.
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
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]
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)
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).
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...
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.
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?
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
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.
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
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.
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...
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 :
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.
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.
Ah, now I see what you mean. That's probably what's going on, in fact.
a|x
oooh, A cube! Of course! Thanks tb.