Fully focused again
For the past two months I’ve been blessed to have been able to focus fully again on my 3D Sacred Geometry engine, named PsiTriangle Engine. This engine is going to be the basis for our upcoming 3D Sacred Geometry Creation program, called Geometrify: Creator.
Getting closer to the metal
I’ve been now focusing on improving my engine since then, getting more performance out of the GPU and calculating as little as possible on the CPU, as the CPU -> GPU bottleneck is a real issue when working with dynamic geometry, you want to keep everything in the GPU memory and not transfer it from the main RAM to the GPU RAM, as it’s a big bottleneck for performance.
Learning the tricks of GPU programming and getting to really feel the power of the GPU has been a marathon run, but I’m finally approaching the performance I’ve been looking for.
Doing complex things is easy, but really just narrowing down everything to the simple essentials, the least amount of calculations needed to be done to achieve the wanted effect, that is difficult and requires countless iterations of writing an algorithm, getting it roughly working, then just iterating over and over on the data models that it uses and approaching the bare minimum needed.
Engineering the heck out of it
I’m an automation engineer by my formal education, and working with 3D equations and math is really an area where I’m starting to see good use of that education. This basis has given me the insight to see that I can understand and dissect any problem, if I just keep drawing and calculating it on paper, until I get it.
So I’m pretty happy now that I got that education, as without it I wouldn’t have probably have the system in place to work like this.
Publicly here I would really like to thank my math teacher at EVTEK, Pirkka Peltola. Math is no easy subject, but he managed to teach it in a way that inspired me to learn it, and he was always embracing the fact that anything you draw on paper, you have to do it as accurate as possibly, as that is the way the process will really develop within you, when you try to approach perfection every time.
Fast line drawing
In the last weeks, I’ve been completely re-writing my line drawing algorithm to utilize the GPU as much as possible. Before this, I had ported an algorithm by Nicolas P. Rougier from Python code to C++, based on his paper here: http://jcgt.org/published/0002/02/08/. But that case was just too generalistic and did too many calculations that I didn’t need, and took a long time to upload the vertexes from the CPU to the GPU, which really killed performance when need dynamic update of all the vertexes for a certain polygonal formation.
So I decided to just rewrite the whole thing from the ground up. Good tool to prototype graphics drawing is http://processing.org, so I first just implemented the algorithm with this, then when it worked, started porting it to GLSL shader code.
Getting to know the Geometry Shader
There is such a thing as the geometry shader on modern GPUs. With it, one can calculate vertexes completely on the GPU, utilizing the massive parallelism of modern GPUs. I implemented my line drawing first completely in the geometry shader stage. Here you can see results for that:
Here all the lines, segments and origo points for the circles are all calculated on the GPU, nothing is done on the CPU except the origo point sent to the shader.
This is pretty great, but there are limitations. First, the geometry shader has to re-draw all the shapes, calculate all the sines and cosines for each line segment, all the time, everytime, on each frame. This is slow.
Second, the geometry shader can only output a limited amount of vertexes. With my GPU, that limit is 256 vertexes of vector4 components. So it’s not really much, can’t do deep recursion with that.
Storing output of geometry shaders into transform feedback buffers
Good thing there also exists a thing called ‘Transform Feedback Buffers’, which basically means you Transform (geometry) and put the results in a feedback buffer, which you then use to actually draw until the geometry changes again.
With this, I could just draw each polyform layer once, and then use the feedback buffer that resides also on the GPU memory to redraw, until the geometry changed, when I need to update the buffer. This got me already much better performance, like this:
Much better, but I was still calculating stuff recursively, storing each circular formation as a separate copy of my base class. This worked well with http://GeoKone.NET, as with software rendering all the data stays in the main memory.
Drawing as little as possible
At this point, I decided that I know what I want to do achieve, and to get there, I really need all the perfomance I need, to make it as smooth as possible. And to do that, the current model of doing things recursively, ie. where a class instance stores numPoints class instances and visits each of them to draw their data, continuing down the path recursively with a parent child model, really didn’t work anymore with the GPU.
With GPUs, what seems to work best is doing things in a linear buffer. You want to have all data continuously available, so you can just loop through when calculating and drawing, with minimum amount of branching and changing buffers when doing that.
Basically you just want to blast the data to the shaders, so they can work on it as parallel as possible, because that’s the strength of the GPUs. I’m still seeking the best way to do this, but with this model I could finally reach dynamic geometry in 3D space with similar performance as with GeoKone.NET.
This is my latest update, showcasing dynamic manipulation of 2D plane sacred geometry in 3D space, that will be the basis for Geometrify: Creator.
Getting there finally :)
I’m developing this engine on laptop GPUs, my faster Macbook Pro having a Nvidia GT750M 2GB card, and my home computer having an ancient Nvidia GT330M/512MB. So I really also have to figure out how to make this fast in order to develop, which is a good thing :) But I can’t wait to test this out on modern beasts of GPUs, which are easily 30x faster than the one on my older laptop.
Anyway, development continues, if you are interested in more updates, follow me on Twitter: https://twitter.com/inDigiNeous, I’ll be updating there more frequently.
Now peace out, and bom! ^_^