During his talk at the live code festival Karlsruhe 2013, David Ogborn (to paraphrase from my faulty memory) said that livecoding seems a very current thing, that something about it seems to be in the air, so much of what we are doing seems to stick and thrive like a form of bacteria.
This festival made it obvious that communities surrounding livecoding are thriving, with representation from Australia, Mexico and Canada as well as European regions and accordingly a wild variety of approaches, techniques and styles that now make up livecoding. The symposium was fundamentally a celebration of this and a chance to experience the diversity directly.
From my scrappy notes and in no particular order, Andrew Brown focused on a describing livecoding technique as an interplay between ‘complexity and succinctness’ in the context of musical research involving data mining large quantities of musical material. Here, as in many issues of creativity in livecoding, the critical decision is where to abstract away details in order to provide a usable and flexible creative environment. His approach is to look for patterns in musical data in order to provide a ground truth, and then make subjective decisions based on practice and performance to build a livecoding interface. Andrew mapped out other useful dichotomies we battle with such as the tension between modelling and simulations of creative understanding vs inspiration, which can come from many places.
Catching up with the rapid development of the phenomenon that is Benoit and the Mandelbrots, their side project “Delbots and the man” is a doomcore livecoding band involving a live drummer – a promising new sonic direction for livecoding. Also on a more technical level their drop function provides a means to allow code to be executed simultaneously in all performers machines, used as a way to accelerate or amplify ‘from scratch’ livecoding techniques in groups.
In contrast, Andrew Sorenson demonstrated the potential to provide liveness and ‘hot swapping’ of code down to the lowest computing levels with Extempore, which can now run on a large number of architectures and levels of concurrency, and now generates code approaching the efficiency of C compilation in many situations.
More reports on the festival, and associated Algorave events to follow.
After rushing around Europe doing a lot of livecoding over the last week (more on that soon) I’m really pleased to announce this workshop closer to home in Falmouth:
CLAN and CREATIVE SKILLS present: CREATIVE CODING taster session for ABSOLUTE BEGINNERS with Dave Griffiths
Friday May 31st 10.30am â€“ 12.30pm
AIR building, Falmouth University, Tremough Campus TR10 9EZ
Places: For 10 people only
Deposit: There are limited places so you will need to pay a Â£15 deposit to secure your place when you book, which will be refunded before the workshop. If you donâ€™t turn up you lose your deposit. To book: Please email: firstname.lastname@example.org
In this workshop for beginners with award winning game designer, creative coder and live coding artist Dave Griffiths you will find out about the emerging art form of live coding and learn how to write simple programmes to create animations in 3D space. You will be introduced to fluxus, an open source game engine for live coding worlds into existence, used by artists, performers and digital practitioners for installations, VJing, games and education.
What will you do? What will you achieve?
You will create 3D animated forms, and have an introduction to fundamental programming concepts, naming of values and processes, recursion and digital representation of colour, 3D shape and texture.
There will be coffees and teas.
At 1pm Dave will talk at a free event-
CLAN – Cornwall Locative/ Interactive Arts Network
1-2pm AIR Sandpit
Speakers: creative coder Dave Griffiths is joined by digital archaeologist Tom Goskar.
Prepare your bicycle clips! Kaffe Matthews and I are starting work on a new Bicycle Opera piece for the city of Porto, I’m working on a new mapping tool and adding some new zone types to the audio system.
While working on a BeagleBoard from one of the bikes used in the Ghent installation of ‘The swamp that was…’, I found (in true Apple/Google style) 4Mb of GPS logs, taken every 10 seconds during the 2 month festival that I forgot to turn off. Being part of a public installation (and therefore reasonably anonymised 🙂 – this is the first 5th of the data, and about all it was possible to plot in high resolution on an online map:
It’s interesting to see the variability of the precision, as well as being able to identify locations and structures that break up the signal (such as the part underneath a large road bridge).
A big part of the look of Minecraft comes from it’s Smooth lighting, which includes an illumination model called ambient occlusion. Ambient occlusion darkens areas of an object based on how obscured they are from a wide area light source, for example an entire sky area, as opposed to a point light source. This is often complicated to calculate in realtime, but with simplified geometric voxels it’s fairly fast to do, building on the code from the hollowing out optimisation I mentioned previously. For each point on a cube’s corners you can add up it’s surrounding empty cubes – the more empty space in the 8 voxels, the brighter the corner needs to be. In this way, we are assuming light is coming from all directions (hence ambient) and don’t need to take into account positions of lights etc.
Here is the raw ambient occlusion lighting in Al Jazari 2, rendered as unlit vertex colours on each visible cube:
Then we add standard direct lighting to the ambient occlusion:
And here is the final image with textures added:
There are a few artefacts in the lighting due to the cubes not all being the same size (in order to minimise the complexity of what is drawn), here is the world coloured based on the size of the octree leaf node – the brighter blue areas are bigger cubes:
Once the ambient occlusion is calculated we only need to recalculate it when surrounding voxels are changed. In practice the splitting/joining of the octree levels when blocks are created and destroyed seems to take care of this in most cases.
;; returns a list of samples to test(define(occ-samples pos)(list(vadd pos (vector -1 -1 -1))(vadd pos (vector -1 -10))(vadd pos (vector -10 -1))(vadd pos (vector -100))(vadd pos (vector0 -1 -1))(vadd pos (vector0 -10))(vadd pos (vector00 -1))(vadd pos (vector000))));; count up the empty voxels and calculate occlusion value(define(calc-occlusion o pos)(let*((samples(occ-samples pos))(coverage(/(foldl(lambda(p r)(+(if(octree-leaf-empty?(octree-ref o p))10) r))0
samples)(length samples))))(min1(*2 coverage))));; helper to set a bunch of verts in one go(define(pdata-list-set! k l v)(for-each(lambda(i)(pdata-set! k i v)) l))...;; uses the cube's position and size to set the vertex colour on each corner(with-primitive my-cube
(translate pos)(pdata-list-set!"c"'(3719)(calc-occlusion o (vadd pos (vector000))))(pdata-list-set!"c"'(101421)(calc-occlusion o (vadd pos (vector size size size))))(pdata-list-set!"c"'(2423)(calc-occlusion o (vadd pos (vector size 00))))(pdata-list-set!"c"'(91517)(calc-occlusion o (vadd pos (vector0 size size))))(pdata-list-set!"c"'(0818)(calc-occlusion o (vadd pos (vector0 size 0))))(pdata-list-set!"c"'(51322)(calc-occlusion o (vadd pos (vector size 0 size))))(pdata-list-set!"c"'(61216)(calc-occlusion o (vadd pos (vector00 size))))(pdata-list-set!"c"'(11120)(calc-occlusion o (vadd pos (vector size size 0)))))
Optimisation is a game where you write more code in order to do less. In Al Jazari 2 doing less means drawing less blocks. Contiguous blocks of the same type are already automatically collapsed into single larger ones with the Octree – but if we can figure out which blocks are completely surrounded by other blocks, we can save more time by not building or drawing them either.
Here is a large sphere – clipped by the world volume, showing a slice through the internal block structure:
The next version has all internal blocks removed, in this case shaving 10% off the total primitives built and drawn:
The gaps in the sphere from the clipping allow us to look inside at how the octree has optimised the structure. The gain is higher in a more normal Minecraft set up with a reasonably flat floor covering a large amount of blocks. Here is the code involved, built on top of a functional library I’m building up on to manipulate this kind of data. It maps over each Octree leaf checking all the blocks it touches on each of its six sides, taking into account that the size of the leaf block may be bigger than one.
(define(octree-check-edge f o pos size)(define(do-x x y)(cond((eq? x -1) #f)((octree-leaf-empty?(octree-ref o (vadd pos (f x y)))) #t)(else(do-x(- x 1) y))))(define(do-y y)(cond((eq? y -1) #f)((do-x size y) #t)(else(do-y(- y 1)))))(do-y size))(define(octree-is-visible? o pos size)(or(octree-check-edge(lambda(x y)(vector size x y)) o pos size)(octree-check-edge(lambda(x y)(vector -1 x y)) o pos size)(octree-check-edge(lambda(x y)(vector x size y)) o pos size)(octree-check-edge(lambda(x y)(vector x -1 y)) o pos size)(octree-check-edge(lambda(x y)(vector x y size)) o pos size)(octree-check-edge(lambda(x y)(vector x y -1)) o pos size)))(define(octree-calc-viz o)(octree-map(lambda(v pos size depth)(octree-leaf(octree-is-visible?
o pos size)(octree-leaf-value v)))