Functy
Functy is a 3D graph drawing package. The emphasis for the application is to allow Cartesian and spherical functions to be plotted and altered quickly and easily. This immediacy and the vivid results are intended to promote fun exploration of 3D functions.
Curvy Screenshots
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.
- Bezier spring with undulating radius.
- Bezier spring with fixed radius.
- Bezier spring with fixed radius using Ubuntu.
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!).
Curves Library Joins the Functy Stable
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!
New Per-Pixel Colouring
There are two significant changes that have been made to Functy recently. The first is improved per-pixel colouring and the second is improved per-pixel lighting. I’m going to leave the lighting to another time and just concentrate on the colouring for now.
Functy is basically a tool for rendering surfaces. Luckily the 3D graphics hardware in modern computers is ideally set up for rendering 3D surfaces; it’s what they were built for. However, those surfaces are almost universally defined by vertices – the positions of points on the surface – meaning that every surface is actually made up of a collection of flat triangles. The result is that graphics cards are great at rendering objects with edges, but less great at rendering curves. Modern cards are so phenomenally fast they can render enough triangles – along with a number of other clever tricks – to make this unnoticeable (nonetheless, it would be great if they actually had the ability to render curved surfaces as first-class objects).
Functy is no different in that it also renders surfaces using triangles. However, it has the advantage that in addition to the vertices, it actually knows the function that defines the surface coordinates and the colours of the points on the surface. Strictly speaking, this means it knows the surface and surface colours to an infinite level of detail.
With the recent changes made to Functy for using vertex and pixel shaders, Functy is now able to properly take advantage of this fact.
Previous versions coloured the surface by specifying the colour of each vertex that makes up a triangle on the rendered surface. The colours in between these points were interpolated, resulting in a smooth transition between different colours at adjacent vertices. This is standard practice and the graphics card can be told to do this – using for example Phong shading – automatically.
Using a fragment shader however, we can improve on this. A fragment shader is a small piece of code that’s executed for every pixel rendered on the screen. By compiling the colour function into a fragment shader, we can therefore calculate the colour accurately for ever pixel rendered, rather than having to approximate between vertices.
The following diagram illustrates this. Suppose we’re rendering a triangle which we want to colour with blue and mauve stripes. The correct result according to the function definitions is a triangle split into two colours. However, if we just colour the vertices and interpolate between them, the resulting output is like that shown on the top right. By contrast, calculating the colour correctly for every pixel gives us the result shown on the bottom right, which is much closer to the correct result we were after.
It sounds like this should be a lot of work, but in fact the result is that (in most cases) it also improves performance. The reason is that previously the colours were calculated for each vertex on the main CPU, taking this processing time away from other tasks that could otherwise be making use of it. Now the calculations are performed entirely on the graphics card’s GPU instead, through the shader processing streams. My (fairly old) graphics card has over 700 processing streams that can run in parallel, allowing the calculations to be performed easily, and taking away the need to do this on the CPU. Everyone’s a winner!
The benefits can be seen most on surfaces with lower accuracy (fewer triangles), but which still have intricate or discrete colouring detail. As you can see in the top right screenshot below, previously the detail would have become blurred or lost (especially if it appeared entirely within one triangle), but can now be rendered in full, with discrete edges as shown in the bottom right image. What’s more, using fragment shaders the colour detail is now entirely independent of the number of triangles rendered, so previous surfaces that needed high accuracy (top left) can now potentially be rendered using as few as two triangles (bottom left).
Although this is a surprisingly simple change to the program, in my view the improvements are impressive, and demonstrate the latent processing power available on graphics cards that often are left unused. Functy has also benefited from similar improvements to the method used for calculating the light reflections from surfaces, and I’ll be looking at this in a future post.
New Year Activity
Development of Functy has dropped off for quite a while as the code was in a relatively stable state, and various other things have been taking priority. But while code commits have been rare, posts on this site have been even scarcer.
I’m therefore pleased to say that over the last few weeks I’ve actually found the time to do a bit more development, and hopefully I’ll be able to post some info about the expected changes as well.
There are two main developments, one a feature addition, the other a major optimisation:
- As well as defining colour functions, I’ve also been adding in the functionality to wrap surfaces with texture maps.
- All of the function rendering code has now been moved into shader programs.
Both of these capabilities work, but need a little more care and attention to get them to a ‘production’ state. For example, adding textures has thrown up a number of problems (such as how to reference the texture in the function file) which I still need to address.
The move to using shaders has resulted in really quite significant changes to the codebase and it’s something I’m particularly excited about. The whole intention with Functy has always been to move the function calculation into shaders; it seemed like a perfect fit. To be honest though, I didn’t think I’d actually ever manage it. However, with a bit more experience and confidence using shaders from other projects, an injection of time and effort, and the impetus that fixed pipeline rendering is becoming a legacy approach, it seemed like a nice challenge to try to tackle.
Although there’s still some more work to be done here too, I’m quite pleased with the result, since not only does it allow the latent capabilities of the graphics hardware to be better utilised, it also generates better results (faster, more accurate rendering).
There’ll be more posts about both of these features in due course. In the meantime, as we enter 2012 I’m hoping it’ll also be possible to find more time to work on Functy further.
Functy deb and rpm packages
Binary packages of Functy 0.22 are now available in .deb and .rpm format. I threw these together this weekend without having a great deal of understanding of what I was doing, so it’s possible they’re just a mess and won’t work at all.
As I use Ubuntu I’m not able to properly test the rpm package. What’s more some corrupt files on my system are preventing apt from working properly, so I’m not even able to fully test the deb package either. It’s all a bit rubbish really, but they’re available anyway as I’m sure they’ll be a better place to start for many people. Fingers crossed they’ll work as expected, but if not I assume I’ll find out soon enough!
You can get the new packages from the SourceForge projects page page, or click on the downloads link in the sidebar.
Functy version 0.22 (beta) released
I’m pleased to say that version 0.22 of Functy is now ready for release. Although this version does fix some bugs, the main improvement is that there’s now an automatic installer for Windows users.
Get it from the download page: http://sourceforge.net/project/platformdownload.php?group_id=259651
Release notes are also available: https://sourceforge.net/project/shownotes.php?group_id=259651&release_id=692280
Functy version 0.21 (beta) released
Oops. After releasing version 0.2 I immediately found a couple of bugs! So version 0.21 is now available as a minor bug-fix release over 0.2.
You can get it from the download page: https://sourceforge.net/project/platformdownload.php?group_id=259651
Release notes are also available: https://sourceforge.net/project/shownotes.php?group_id=259651&release_id=690043
Functy version 0.2 (beta) released
Functy is a 3D graph drawing package. The emphasis for the application is to allow Cartesian and spherical functions to be plotted and altered quickly and easily. This immediacy and the vivid results are intended to promote fun exploration of 3D functions. Functy can be built for GNU/Linux or Windows.
This 0.2 release is still beta, but has a number of improvements over 0.1 including:
- An improved user interface.
- New functions that can be used, such as cosh, atan, sec, exp, abs etc.
- Spherical coordinate plotting of functions.
- Various smaller bug fixes and changes.
To find out more or download the latest version, please visit one of the following pages.
Project web site: http://functy.sourceforge.net
Download: https://sourceforge.net/project/platformdownload.php?group_id=259651
Sourceforge project site: https://sourceforge.net/projects/functy/
Release notes: https://sourceforge.net/project/shownotes.php?group_id=259651&release_id=678510
Lissajous and lava lamps
Time for another demo video. This time I’ve tried to create a 2D function on a 3D surface by playing around with the colours of some function.
In the 90s I used to love watching clever computer demos. One of the visual effects that was sometimes used was that of viscous circles or spheres that would meld together when they moved close one another. This created the kind of effect you get with a lava lamp. In this demo I try to recreate this effect using a couple of functions and a computer that’s probably several thousand times more powerful than the ones the demos ran on. Does the resulting effect work? See for yourself!
I do apologise though for the terrible delivery.
Spherical co-ordinates
So far Functy has worked only using Cartesian co-ordinates, but I’m currently working on code for the next release to allow functions to be defined using spherical co-ordinates too.
Spherical function plotting is already working as you can see in the screenshot. It seems to produce some nice effects that are quite different from those you generally get using Cartesian functions.
The tricky part seems to be getting the code for both co-ordinate types integrated nicely together, and also sorting out a suitable user interface to allow them both to be added seamlessly.
The reason the code is turning out to be tricky is that I’m trying to develop using object oriented techniques, but using C rather than C++. I know it’s perfectly possible to do this (and do it well; although not necessarily by me!), and so far there hasn’t been much problem. However, I’m now in a situation where inheritance would seem to be the perfect technique to use. Most of the methods needed for the two co-ordinate systems are the same, so in C++ it would make sense to use some virtual interfaces to define them and inherit these from a generic function type. Unfortunately I’m not sure if this is going to work well in C.
It seems like a silly thing to get stuck on and it would be nice to get the spherical functionality into the next build. I’m hoping the best method will become clearer as things progress.





