
Quartz Composer Quaternion Julia GPU Ray Tracer with AO
2 months ago
This is a Quartz Composer GLSL shader patch that ray traces a Quaternion Julia set. The shader is ported from Keenan Crane's Cg version described here: devmaster.net/forums/showthread.php?t=4448
I've added a crude Ambient Occlusion addition to the shading as part of the ray tracing process is to calculate the distance to the nearest part of the fractal isosurface and so we can get an AO effect almost for free.
Without 4x super sampling I get up to 30fps @600x400 on my iMac with a NVIDIA 8800GS gfx card.
Update: see the blog post for more details and downloads: subblue.com/blog/2009/9/20/quaternion_julia
I've added a crude Ambient Occlusion addition to the shading as part of the ray tracing process is to calculate the distance to the nearest part of the fractal isosurface and so we can get an AO effect almost for free.
Without 4x super sampling I get up to 30fps @600x400 on my iMac with a NVIDIA 8800GS gfx card.
Update: see the blog post for more details and downloads: subblue.com/blog/2009/9/20/quaternion_julia
-
Vimeo: About / Blog / Developers / Jobs / Community Guidelines / Community Forums / Help Center / Site Map / Merchandise
/ Get Vimeo

Previous Week
Great minds thing alike! I did the same thing a while back, but without the AO.
machinesdontcare.wordpress.com/2008/05/01/quaternion-julia/
You should also take a look at Tebjan Halm (tonfilm)'s generalised isosurface raytracer for VVVV. The HLSL code can be easily ported to GLSL
machinesdontcare.wordpress.com/2008/05/08/vimeo-2/
I'd love to see if you could apply the same AO effect to this, too. I'll provide the GLSL code, if you're interested.
Great work, mate!
a|x
youtube.com/watch?v=G39bL31zXus&feature=channel_page
which has self-shadowing builtin. Maybe he added that himself, too.
a|x
Keenan's code has standard raytraced shadows. The AO approximation I added comes from counting the number of steps it takes to hit the isosurface. The step size is calculated as the distance from the current point to the nearest point in the isosurface in any direction, so the areas that are more obscured are going to need more steps as the step size will be smaller. It's by no means physically accurate, but adds a significant visual improvement at practically no additional cost to the rendering.
I'm in the process of writing it up in a blog post at the moment, which should be online soon.
I've going to have to spend some time going through your blog archive, I only subscribed to your RSS feed this year so missed all your older good stuff!
Re. the machinesdontcare archives, I wouldn't worry too much about trawling through them, to be honest. When it comes to GLSL stuff, I've pretty-much been working blind really- translating various chunks of shader code I've found into GLSL, without really understanding how it's really supposed to work. You'd be much better starting from scratch, as you seem to have a much firmer grasp of the concepts and mathematics involved than I've ever had.
a|x
a|x
Re. the GLSL stuff - I recently invested in new the GL box set. Quite intimidating but it's already proving to be indispensable!
a|x
I also wasn't rotating the light-source, so the effect is more of the surface itself rotating, than of the camera moving around it. Maybe I'll add the option to do one or the other at some point.
Having said that, your implementation looks more impressive than mine, anyway ;)
I should probably have done the matrices in the shader, too. I was initially put off trying to do this because I thought it wasteful to do the same calculations per-vertex, rather than just once externally, but given the massive speed-difference between JavaScript running on the CPU and matrix maths on the GPU, I'm sure doing all the required calculations in the VS is by far the better option, even if it then does have to do the exact-same calculations 4 times (once for each vertex of the quad/billboard).
a|x
I'm intrigued by the way you setup rotation. It's quite different from the way I did it.
I created a single rotation matrix in a JavaScript patch, then used that in the Vertex Shader to transform the texture coordinates and the camera-position, which I passed to the Fragment Shader as a varying.
Not sure of the relative merits of each approach. I like the fact yours shader is more self-contained though.
a|x