May 2012 Archives
I’m very pleased to announce the release of Functy version 0.24, which can now be obtained from the downloads page.
The main changes from the previous version are the following.
- Addition of the new curve function type. This complements the existing Cartesian and spherical functions by allowing parametric curves to be defined with cross-sections based on cylindrical co-ordinates.
- All function types can now be rendered either using the CPU (as before) or entirely using the GPU.
- GPU rendering provides per-pixel lighting calculated using the derived normal function (rather than using interpolated normals as used by most per-pixel algorithms).
- Available for Windows and Linux, and also as a new ARM Debian version for use with the Raspberry Pi.
Functy is still very much a work-in-progress, and won’t be entirely bug-free, so if you stumble across a problem or have any difficulty with it please let me know.
The latest version of Functy in the repository now has a (roughly) working version of the curve rendering code. This allows a cylindrical coordinate cross section to be extruded along the length of a parametrically defined curve. In other words, something like a tube.
The code is fairly incomplete. Trying to define functional colours will cause a crash, and vertices are all positioned on the CPU, so that animation isn’t particularly efficient. Both of these should be fixed soon, including GPU rendering of the entire curve.
Here’s a brief video demo of this early code to give a flavour of how it can be used.
Having spent far too much of my weekend playing around with a Raspberry Pi, I’m pleased to say that this has at least resulted in a nice new ARM Debian package of Functy to run on the tiny credit-card-sized computer.
Even though the 3D graphics are a bit slow right now, I’m thoroughly impressed that the Raspberry Pi was happy to build and run Functy with practically no modification. I wasn’t expecting that!
There are more updates to Functy in the pipeline, but in the meantime, the new Raspberry Pi build (which even contains functionality not yet found in the other versions) can be downloaded from the downloads page.
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!
Designing a really good library is a difficulty task. Since around August last year I’ve been writing a program called Knot, which I also recently open sourced. This makes extensive use of 3D Bezier tubes to render Celtic Knots, and having written the code for this, it seemed sensible to try to integrate it into Functy, to allow arbitrary tubes to be rendered using curved cylindrical coordinates. So, that made it a perfect candidate - or so I thought - for implementing as a library. This way, improvements from the Knot code could be easily merged into Functy and vice versa.
Designing the library turned out to be tricky, especially the task of managing and animating all of the curves. I figured that if I put the effort in to getting the library right, it would make the process of integrating into Functy that much easier.
I was wrong. After painstakingly implementing everything needed in the library, I tried to integrate it into Functy, only to realise that Functy already has all of the management and animation functionality needed. Given that I wrote the Functy code, you’d have thought I might have know this.
The consequence is that I’ve ended up dropping all of the curve library methods and cut and paste the relevant code straight in to Functy. If I hadn’t done this Functy would have ended up with two totally separate lists of functions, two separate animation steps and two separate update steps. It would have been a mess.
It’s taken longer to modify the curve code for Functy as a result, but the final structure is much better. Unfortunately it also means the library is now redundant. I’ll have to find some other use for it.
There’s a design moral to this story I’m sure, but I’m not exactly sure what it is. I’ve ended up with a nice clean library implementation that doesn’t work for what it was designed for, a new implementation that doesn’t use this library, and what seems like a lot of wasted time. It feels like somewhere something went a bit wrong. At least Functy can now render curves, so even if it was a circuitous route, maybe the journey wasn’t entirely wasted after all.
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!).
The Curves library allows various types of tube-like object to be rendered in 3D. Things like Bezier tubes and parametrically defined curves. Although it’s still got a shed-load of functionality missing, it’s reached a more-or-less stable state, which means it’s time to integrate some of this functionality into Functy.
The idea is to allow parametrically defined curves to be added to Functy graph scenes. At the moment it’s not really possible to do this using the existing surface and spherical functions, but I’m hoping it’ll make a useful addition. For example, it would allow 3D charts (line charts or bar graphs) to be easily generated, which could be quite neat.
The library has grown out of Bezier curve rendering I needed for my Knot application. One of the key features of this is that it’ll output Stanford Triangle Format (PLY) files which can be imported into other modelling applications, or even used to create 3D prints.
The plan is to eventually add similar functionality to Functy, and hopefully the addition of this library will pave the way for a collection of new interesting features!