The last two weeks of summer break have given me the opportunity to give Functy some long-overdue attention. As I mentioned in my previous post, one of the improvements I’ve been working on has been dynamic shadows, and these are now fully implemented. The result is a big improvement in the visual fidelity and sense of depth in the visualisation. You can see the difference in the two screenshots below and I’ll include a proper comparison in a future post.
The next step will be to test out ambient occlusion, as kindly suggested by Andrea Bernabei (@faenil). I’m not sure how well this will work with the type of functional objects rendered by Functy, but it’s worth investigating. Ambient occlusion produces the sort of shadow effects more likely to occur indoors where the light tends to be more scattered, as compared to directed lights or outside direct sunlight, as the current version produces. However, research has shown that ambient occlusion gives a heightened sense of depth as compared to direct shadows, so it’ll be interesting to see the results.
The second major change has been to the user interface. This has been completely rebuilt from the ground up to fit with a single window workbench-style interface, as opposed to the previous multiple-window toolbox-style interface.
Personally I’m a big fan of multi-window interfaces; it should be the job of the window manager to allow you to arrange and configure your windows however you want. Sadly most window managers seem to be lacking in the flexibility department, and managing multiple windows becomes an exercise in hide-and-seek, trying to find windows that got lost behind others like a stack of papers on a desk. So, even though it’s not the perfect solution, I’ve converted Functy so that everything is visible and available in a single window.
I have to admit that the result does look more professional and I think it’s a positive change. I’m not quite sure what will happen if things get more complicated, but it works well for the timebeing.
There’s still a fair bit of work to be done before this can be given a full binary release, such as updating everything to work on Windows, and switching from libglade to GtkBuilder (this may be for a future time). Feel free to test out the version from source (it’s very easy to build, honest!) in the meantime.
Shapeways delivered a new batch of 3D prints recently. I was particularly pleased with the Alien Egg print of a spherical function with the formula:
radius = (3*(0.5+(sin(cos(a)+(p*((3+cos((pi*0.3)-1.5))/4))*10)**2)+((6/6.6)*((2+sin(8*a))/3)**4)))*sin(p)+(4.3*(1-(sin(p)**2))),
colour (R, G, B) = (r/8, (3+sin((a)*8))/5, (3+cos(a*8))/5).
The print is actually rather small (just 6 cm diameter) and the ridges of the shape are really quite delicate. In spite of this, the 3D print has come out really very similar to the original design. I guess you might expect it to be pretty similar, given the way it was produced directly from the model! However, if you look really closely at the original you can see the strata through the object created by the printing process. What I’m really impressed with, though, is the colour produced. I’d expected this to be a bit washed out, but in practice it’s a pretty impressive match.
Below is a comparison of (from top to bottom) the Functy render, the 3D print and a render done using Blender Cycles. In case you’re interested and your browser supports APNGs, there’s also a peculiar animated version!
One of the difficulties with 3D visualisations - and network visualisations seem to suffer especially badly from this - is that while they’re a great way to represent complex data, they rely on animation for much of their clarity. This stems from the fact that the third dimension is illusory. The fact is we’re still largely stuck with 2D screens that our 3D images get projected onto. Until we move to proper volumetric displays, even the current attempts at 3D (stereoscopic) displays won’t fix this.
For the moment then, the best way for us to understand the lost depth component is by shifting our perspective, or in other words, by moving things around.
However, there are other ways to approach this and in the past I’ve been incredibly impressed by the way blur can be used to improve the perception of depth. This can give a really nice effect of camera focus, where different parts of the image have different levels of blur applied depending on whether they’re in or out of focus.
Testing this on some of the network graphs that I’m currently working with has produced some really quite nice effects. Ironically, by making parts of the image less clear, the overall coherence and clarity of the image is improved substantially. Here are a couple of screenshots of a random network with focus blur applied, both from up close and from a further distance.
The effect is achieved by rendering the whole image to a texture framebuffer. A very simple fullscreen shader is then applied, which increases or decreases the level of blur for a given pixel depending on the z-buffer depth value at that point. It’s a really very simple technique, but in my opinion produces some quite effective result.
This is one of the reasons why shaders are so phenomenally powerful. The depth blur is a very short program, but it needs to be executed for every single pixel of the image. That’s a lot of pixels, and a lot of computing power is needed to do this. Applying a shader program in parallel across the whole image is hugely more efficient than getting the CPU to do it. This allows it to be applied in realtime for each rendered frame, without stretching resources, even on my relatively underpowered laptop.
As part of an experimental game project I’ve been trying to use the Functy rendering routines to visualise network structures. At the moment it’s at a very early stage, but has - I think - already generated some interesting results.
The screenshot below shows a network of 60 nodes, each one rendered as a spherical co-ordinate function, joined together using links rendered as curves. I just plucked some simple functions out of the air to see what the results would be like but am hoping to extend it with more interesting shapes as things progress.
The various parts of the network are a little hard to discern with a static image, but when I tried to capture a video the result was a mess of fuzzy artefacts (I think there must be something going wrong with my screen capture software), so I gave up on that.
The next step, after neatening up the code, is to arrange better animation of the nodes and links, with dynamic movement based on things like the forces between the nodes. I’m hoping this will produce some really nice effects, and if anything comes of it I’ll put a bit more effort into getting a successful video capture.
After prompting by Tony’s superb gallery of images, I’ve spent a bit of time playing around using Blender to render models created using Functy.
This has also prompted a bit of extra functionality, and I’m hoping it will soon be able to export out multiple models from Functy to support animated functions. Using the current experimental code (there’s no front-end yet, but it’s in the pipeline) I managed to generate a kind of animated mercury whirlpool. It’s up on deviantart, and if you’re happy to wait for the download, please do take a look at the full animated version.
One of the obvious but neat consequences of having the new STL export functionality from Functy is that the generated models can be imported in to other things. One of these things… well, p3d.in provides a clever HTML5 in-browser model renderer, which means the models can now be rendered interactively directly into this site (or indeed any others). Check out this version of a ball made from string, generated as a couple of curve functions in Functy. Just click and drag to rotate the model. And if you like it, you can even print a copy in 3D!
This morning I received a brand new Raspberry Pi through the post, and this evening it took only minutes to get it up and running. It’s quite a brilliant piece of kit for a phenomenal price. I’m quite happily typing this text on it without problem.
What’s more, to my pleasant surprise, I managed to get Functy working with only minor tweaks. I thought the fact it’s the ARM version of Debian might mean there would be problems with the OpenGL libraries, but it seems like it’s worked fine. Even the shaders are compiling and running, although it runs more smoothly when it’s just VBOs.
So the 3D rendering isn’t fast, but to be honest, I’m pretty much flabbergasted that it’s running at all, and it’s doing it at 1920×1080. Not bad for £25 worth of hardware. Correction: absolutely amazing!
The Curves library is currently being integrated into Functy in order to provide parametric tubes to be added to function scenes. To give an idea about the sort of results this might allow, here are a few screenshots taken from the development version.
In all of these images the tubes follow a path constructed from cubic Bezier curves:
((((1 - a)3) × P1) + (3 × ((1 - a)2) × a × D1) + (3 × (1 - a) × (a2) × D2) + ((a3) × P2))
where a is the parametric variable, P1, P2, D1 and D2 are the control points. It’s a bit crazy using Bezier curves for this since the library could handle a spiral far more easily, but it was just a product of the way the demo developed. For the first image the function used for the radius was the following.
((2 - cos((((s × a) + o) × 6 × π)) + (sin ((12 × p)) / 5)) / 2).
Here a and p are the parametric variables for the position along the curve and angle around the radius respectively. The values s and o are offsets and scaling factors that are changed for each quarter-circle segment of the spring.
The intention is to allow these functions to be entered directly into Functy to generate curves such as these. There’s still quite a bit of work to be done. Although the Curves library is coming along, this still needs to be integrated with Functy, and the shader code for these parametric tubes also needs to be implemented (it’s certainly possible, but I’m anticipating problems!).