The last time Hackerfall tried to access this page, it returned a not found error. A cached version of the page is below, or clickhereto continue anyway

BRU-3, The Logo Generator | BRUTALISM

As a first project to be madeunder the BRUTALISM moniker, I decided to design a generative logo to represent the studio’s identity online. Here’s how it was done, from paper sketch to final product.

Sketches

Having a background in Belgrade’s late 90s and early 2000s graffiti scene, I developed a certain aesthetictaste which has (hopefully) kept evolving since then. I wanted to fuse my love of generative art, system modeling, and the aestheticthat has defined me throughout the years. I wanted toencode my taste, if you will.

It started bythrowing some rough sketches on paper and immediately attempting to findthe rules for even the smallestof decisions “Why is this line at this angle?” “Why does this letter look better with a spike, and this one doesn’t?” and so on.I wanted to capturethe flow of letters.

It was immediately obvious that I need some kind of skeleton which willact as a placeholder and guide for each letter, and which can be geometrically transformed without the code for the letters themselves having to worry about it. I wanted a clear layering between subsystems.

So I started messing around with addingthe “bone” system. At the time I was deep intolearning Clojure for the first time, so I decided to give Quil a chance since I could later export the projectas both a standalone app, and as a JavaScript fileembedded into a web page. (If I were to do this again, I’d probably go with pure ClojureScript + Three.js.)

40 lines of code later I had the following:

Hey, I was very happy when this first appeared.

I then proceeded to add “frames” which hanged onto the bone structure.

This was already going in the right direction. I could tweak the angles of each bone relative to the ones next to itand the relative height difference between letters. The flow was starting to emerge. And it was just 20 lines of code.

I proceeded to sketch some more ideas on paper.

A certain style was starting to emerge. At this point I could alreadypicturehow this would all look like when combined with the distortion fields I planned to add after the basic styling was implemented.

Adding details to frames

I was satisfied with the aesthetic of the dents in the frames representing letters, so I went on to encode it.

At this point I was knee-deep in functional programming for the first time, so it took me a while to figure out how to best transform the edges asymetrically. The spikes were always being drawn in the same direction (clockwise or counter-clockwise), and I had a hard time figuring out how to parameterize this. After I figured it out though, it was very enlightening and made meappreciate Clojure on a completely different level. I was modelingtransformations of data, not programming.It’s one of the mostconcise and elegant 70 lines of code I’ve ever written.

Adding flow

This was a good basis, but it still looked like some fixed sprites jiggling left and right. I started researching vector fields a while ago, and this was just begging to use them.

A vector field is an interpolated n-dimensional array of vectors, which you can query for resulting vectors at any point in space. On the page I linked above you can see what they look like in three dimensions and how I used them to distort the generated terrain. Here’s whatthey look like in two dimensions:

So, there’s a grid of vectors (4×4 forthis picture if I remember correctly) which are pointing in random directions, and at each point in space you can query the field for a resulting vector which is calculated by interpolating the directions of the four vectors nearest to it. (In three dimensions, you query 8 vectors, one for each corner of the cube). In this case, I used a 4×4 vector field to display a debug view of24×8 vectors (approximately). So a 4×4 vector field was interpolated to show at a 24×8 resolution. The good thing about vector fields is that they’re continuous. You can query themat anyresolution you want.

I then proceeded toread vectors from the vector field ateach frame’s vertex and apply the offset read from the field to the vertex itself. Effectively, I was using the vector field tomove the frame geometry around in a very, very non-linear way.

This was beginning to look good, but unfortunately the picture above was hand-picked from dozens of “ugly” ones. There were lots of cases where the distortion was completely unsuited for the geometry built in the previous pass (bones + frames + frame style). This is what I didn’t want it to look like:

Flow was there, but it was completely uncontrollable. The letters were stretched arbitrarily (look at that “B”, for heaven’s sake) and there was no unity of distortion – some letters were stretched out, while some were squeezed to nonrecognition (the “M” on the far right).

Taming the distortion

I needed a way to control the vector field. It had to be generated in a way that was parametric and allowedtweaking in a sensible manner.

I started analyzing which vector fields generated better looking results by manually regenerating the logo hundreds of times, and trying to infer the law by which the “good” distortion behaved. This took a couple of days of obsessive staring into one generated logo after another, but at the end I figured out a solution.

The logos looked best when the vectors aroundthe frame geometry weremostly facing toward it. I could have easily just made them always face towards the geometry (with slight offsets), but then the logo would just look squished and uniform. Additionally, if I were to simply make a system that made vectors on the upper part of the screen face down and vectors on the bottom part face up, the flow would be lost everything would be one long straight line.

So I came up with a concept I calledfault linesattractors which would “turn” the vector field’s vectors towards them.

The fault lines aregreen in the picture above. You can see that the vectors tend tomostly pointtowards the nearest fault line segment. You can also see that the logo’sgeometry follows the positioning of the fault lines if a fault line goes up, the logo geometry around that line also goes up, etc.

This approach preserved the turbulent and random nature of vector fields, while giving me the abilityto control their influence on the geometry in a precise way. It was done in30 lines of Clojure.

Sculpting the system

After that, I had everything in place and I could proceed to sculpt the system to suit my taste, to encode it. This took a lot of time, roughly the same amount of time it took to implement the system. Here are a couple of screenshots I captured along the way (some of them are screengrabs from an earlier version of this site):

You can see that I have now completely hid the original symbolof each letter and that the letters as such are now hidden behind their twisted shapes. This was intentional. By looking at dozens of logo variations, sometimes a variationcomes up that reveals a shape of one or two letters to the observer.This way the logois slowly being deciphered, hopefully.

You can play around with the logo by clicking on it on the top of the page, or by checking out the GitHub repo and tweaking it on your own machine.

Obey the Algorithm.

Continue reading on brutalism.rs