Screens is a generative series that launched on ArtBlocks Curated on January 31st 2022. This page contain additional information and background about the project. To buy a Screens piece, use a secondary market site such as OpenSea
- Screens Layers — Experience the build-up of a random Screens piece from the collection.
- Screens Surfer — Browse ephemeral, out-of-band, Screens piece.
- Screens Scaler — Experience your favourite Screens piece at different scales, uncovering what lies outside of the frame.
Screens is the continuation of an idea and vision that started with my Constructive series (released in August 2021). The primal aim was to explore the aesthetics offered by silk screen printing techniques, and this naturally led me to explore the poster prints from both Bauhaus artists and Russian constructivism artists. Thus, while working on Constructive, the focal points where strong geometric compositions, strong simple colour palettes, gradients using a rendering technique mimicking screen printing.
Constructive was very much a handheld series. While it is generative in nature, the macro composition was decided beforehand. I did enjoy the result immensely and I knew almost immediately that I wanted to explore this aesthetic in a long form format. Thus began the thought process that led to Screens.
With Screens I wanted to continue my main focus: Strong geometric shapes and gradients together with the signature grainy rendering style. However, the approach taken with Constructive wasn’t scalable and besides, I didn’t want to rehash a finished project.
The idea of extruding lines into screen-like shapes and drawing them in an isometric view first came together with the idea of using flow fields to generate the lines. I very quickly cast aside the idea of flow fields for several reasons, one being overexposure to the concept, and one being a strong affection for pure geometric shapes in this project. The basic idea was born though, and could easily be used with other things than flow fields.
All of this happened without any coding or sketching at all. This is pretty much on par with my process, as I often design and develop ideas purely in my head. Then, when I finally decided to sit down and code, the central part of the system was completed in 2 days, mainly because the result matched my vision so well (this is not always the case). However, following this came several months of trying out ideas and fine tuning the algorithm. In order for Screens to work as long form generative art I had to embrace a level of chaotic behaviour that I would usually refrain from putting out there beyond my control. Thus, an enormous amount of work was put into keeping the chaos in check so that I could rest assured that every piece would work. Most of this work, and the months that went into it, is obviously not visible since it was concerned with what shouldn’t come up. If the work done is not apparent I have succeeded.
Screens, being a series generative artworks, is of course based on some system, some rules, that control how things are made. While I’ve strived to make Screens something that can be appreciated in itself without knowing anything about the system (or even know that a system exists) I do believe that it may interest some to look down in the engine room. You may do this out of curiosity, or for understanding the collection better as a whole. This section will dive into a no-code description of the system, both describing the rendering, as well as how the composition is made and what the different features encode.
The rendering engine in screens is created to mimic how a silk screen print comes to life. Each piece is made up of a set of discrete colours and for each colour a monochrome template is generated with smooth gradients. The template then gets converted to an (almost) pure black and white image by changing the smooth gradients to the grainy noise that Screens is known for. After this has been done, the black parts of the template is coloured with the colour of the screen and the template is then merged into a master image.
Screens #923 — finale
I had to make some concessions as to how close I could follow the print making technique, mostly when it comes to the alignment shifts. The first iteration was true to its heritage in that the templates was generated perfectly and the misalignments was only added when the template was merged with the master. However, being based on pixels, rotating and moving the template after generation resulted in noticeable quality degradation. Because of this the misalignment was performed when the template was generated to ensure each pixel had the exact grayscale value it should.
The order each template is applied in are not random. Each palette is ordered roughly by increasing darkness. This was done partly to follow how you would generally apply paint, since lighter colours have a harder time covering up darker colours. Pixels do not have this issue of course, but I felt it made sense to keep this order. A nice and unplanned side-effect of this choice is that the build-up of the piece becomes much more suspenseful because the final piece tends to get more and more structure with each subsequent addition of templates.
At its core, Screens is a bunch of lines extruded into screens in the y-direction and drawn with a random colour gradient applied to them. There is obviously a bit more to it, so lets talk about that, starting how the lines are made.
Lines are not drawn at random — they have some structure to them. This structure is provided by the concept of actors which provides geometric direction to a set of screens that will thus follow the same rules. How these actors are combined to make up the final structure is defined by the style (see Scenes below). There are 5 types of actors available to choose from:
This actor creates screens as circle arcs at different radii from the same randomly selected center. Arcs are created by randomly selecting a radius, a start angle, and a span measured in radians. The radius selected can be biased towards lower values giving a denser look. Otherwise it is uniformly distributed between the minimal and maximal radius allowed. Since the span of the screens are based on radians it follows that screens farther from the center tend to be longer than those closer to it.
This actor is in many ways equal to the circular actor except the screens follows the circumference of a square rather than a circle. It has the same possibility of becoming condensed by biasing the distance to the center towards lower values. It also follow the same rule as the circular actor in terms of screens farther from the center being longer in general. This is because the span is given as a percentage of the circumference of the square at the given distance from the center. The square actor is the only one capable of creating sharp turns in its screens, giving it some unique compositional abilities.
The radial actor is one of the more versatile of the five. It creates screens that radiates from a randomly selected center. The start distance and angle relative to the center is chosen at random. All screens from the same radial actor follows the same rotational momentum, but this momentum can vary between different radial actors, giving rise to both strongly winding spirals and almost straight lines from the center. While screens from the same radial actor cannot cross each other, they have the potential to get very near to each other. Because of this each screen is terminated if it gets within a threshold distance to other screens from the same actor.
This actor is probably the simplest, but has the possibility of creating the some of the strongest clean composition. Further, due to it’s simplicity it works well in unison with other actors where it creates interest without overly complicating the composition. The screens from the straight actor all follow the same angle and is distributed along a shared line. Like circle and square actors, the screens from a straight actor can be condensed around the shared line or uniformly distributed out to a max distance from the line.
This actor sets up 4 or 5 parallel lines that acts as control points for a clamped open B-spline. Each screen is based on a location along the control point lines, e.g. a screen placed at 0.25 would derive its control points a quarter along the lines. Further, it has a start and end from 0 to 1 (B-splines are parameterised between 0 and 1). As with radials, Spline screens has the potential to get very close to each other so they also check for and terminate at too close proximity to other screens. Spline actors are the only actors capable of creating screens with a more wavy feel and the possibility of changing directions multiple times. This offers some unique possibilities in composition.
The actors define how screens are created - the scenes defines which actors are used and in what capacity.
Potentially the most easily recognised scene. It consist of a single actor placed inside the frame creating 100 screens. Because a single actor cannot create intersecting screens the hero scene has a very clean and striking look. However, there is also not much room for emergent compositional traits to arise.
Like hero, the collapse scene only consist of a single actor type. However, it contains 50 of these actors placed both inside and outside the frame, each giving rise to a single screen. Because of the ensuing chaos this scene is the one with the highest potential for unique emergent compositions and quite a few of my own personal favourites are of this style. The reason why this approach refrain from resulting in pure chaos is that each screen shares a common dynamic, thus unifying them in the same compositional harmony.
Company is the last of the scenes only using a single actor type. It consist of two of the same actors, placed inside or outside the frame and each creating 50 screens. This style is often one of both harmony and strong geometries, though certain setups can of course create dissonance.
This is like company but with two different actors instead of two identical ones. While the name implies tension, that is not always the case. The combination of e.g. a circular and straight actor might just give rise to a some of the interest that the cleanness of a hero lack.
The crowd scene consist of three actors, two of which are of the same type. Each of these gives rise to 30 screens Once you up the number of actors to three there is a high probability that things end up dense and chaotic. The harmonics of the two actors of the same type somewhat works to counteract the chaos, but the last actor is bound to throw a wrench into the effort. Thus this style will often balance between harmony and tension.
Order and Chaos
The last scene style consist of 3 actors emanating 30 screens, just like the crowd style. However, this time all 3 actors are of different types. It follows that any type of harmony is generally only obtained through chance and that chaos is the name of the game. Remember that chaos is not used derogatory, but simply to describe the feeling the composition elicit in the viewer. Screens has been designed to encompass this diversity in emotional responses to the compositions — an overabundance of harmony quickly becomes boring.
With the exception of the hero style screens are bound to intersect (I guess it is theoretically possible for other styles to not have any intersections but I’ve yet to see it). These intersection are what gives rise to the diversity of forms, dynamics, and negative space in screens. However, intersections are not treated evenly by all screens pieces, and how they are treated have a huge effect on the feel of the final piece. The behaviour is encoded in the Clipping trait.
Spacious is very much the “standard” look of screens. For every intersection of two screens one of them is clipped at random and segment around the cut is removed in order to leave some distance to the intersection point and properly separate the two resulting screens from each other. This approach ups the amount of screens considerably thus giving rise to more variation and visual interaction. However, due to the buffer zone around each intersection, it retains a level of order — no two screens are too close to each other.
Very much the antithesis to spacious. Here intersecting screens are kept as is (not mentioning the work done to make the intersection point look neat). This all have two effects: First, the lack of any cutting means that the final piece will contain longer screens in general resulting in longer gradient; Second, the fact that screens are touching naturally creates more visual tension and often end up resulting in an aggressive piece, especially if the screens are stroked. The longer gradients possible here means that screens can end up only showing a single colour in the visible area, thus creating much more potential for interesting negative space to form.
Dominating might seem like a variation of spacious but it’s effect can be massive. Like with spacious, intersections are clipped and a buffer zone is applied. However, with dominating a single actor is selected to always “win” in the battle of who gets clipped. This means that screens from a single actor is left intact while the remaining screens fight it out. It is natural that the dominating actor ends up, ahem, dominating the piece.
The last trait having a strong direct impact on the composition is the height of the screens. The concept is pretty simple and encodes how far downwards the line is extruded to make a screen.
Tall screens are basically extruded to infinity making sure that nothing behind them will ever be visible. This is the prevalent look and the setting that most often leads to harmonious and dense compositions.
Medium screens are just tall enough that they often times look tall, but thin enough that there is often a couple of places where you get to see underneath the screen and what is behind it. This leaves room for the solid background colour to shiny through giving rise to interesting negative spaces and shapes that would otherwise not be possible.
Thin screens are, well, thin. So thin in fact that often the resulting composition is dominated be the background and the negative space.
With the varied trait one actor will get tall screens while the remaining actors will get screens ranging from thin to medium. The effect is that instead of the background being visible underneath the screens you’ll see the structure of the tall screens. Visually you often get the feeling of seeing the thinner screens floating in between the infinitely tall screens.
Colours are a big part of Screens. They are used to imbue emotions, of course, but also as a compositional tool because screens may visually merge if they overlap while sharing the same colour. This effect gives rise to some of the best emergent features in the series.
The colour palettes define the set of colours a piece can choose from. However, it does not dictate that all colours must be used, nor how. Still, the palettes imbue certain emotion and feels that will transfer to the final piece. I do not want to transfer my own emotional responses to these colours to others (more than I’ve done by naming them), as I believe in the observer creating their own narratives of a piece. Thus, below are simply a few representative pieces for each palette, showing their range:
Somebody that I used to love
Dreams of a Distant Memory
While the palette sets the stage, the colouring scheme defines the feel. While the different styles doesn’t scream at you they do carry an enormous weight in terms of the composition of the final piece.
This is the “everything goes” version. For each side of each screen two colours from the palette are chosen at random which defines the gradient. The result is definitely the busiest of all the colour schemes, especially when combined with primary colour palettes such as Bauhaus.
Here, every actor gets a colour assigned from the middle range of the palette (that is, every colour except for the lightest and darkest). Each side of each screen then randomly selects to colours from the assigned colour + light and dark. This creates very well defined actors, bringing more structure to the piece.
Gradient works kind of like Condensed, but instead of getting a colour assigned based on which actor the screen emanates from, it gets a colour assigned based on its position along the y-axis. As with condensed, it create structure, but the structure comes from proximity, not from the actor, thus creating groupings between otherwise unrelated screens.
This colourway is probably not one you would notice… It’s like a more cool-headed chaotic. Like chaotic, each side of each screen is assigned 2 colours at random, with the single constraint that the two colours must be adjacent in the palette. Since all palettes are sorted roughly by darkness it means that all gradients in the piece ends up being very calm and low-contrast, resulting in an overall less aggressive vibe.
Wait, somethings not right…
After reading this you might find yourself browsing the collection for specific traits to get to know them better and you may stumble upon something that doesn’t quite fit… A Crowd with only 2 actors, a chaotic style with colours missing — you name it. The truth is that not everything is under my control. Things get drawn both inside and outside the frame and while everything influences the end result, it might not be apparent how or when said influence happens.
Take the case of #957 - the space station.
Classic hero, right? Wrong! In reality it is an antagonists… We can see this if we zoom out:
Screens #957 — Zoomed out
This is what happens if an artist gives into and embraces chaos. So is 957 a hero or antagonists? Who cares… The traits in Screens are more about the potential in piece than hard truths about the outcome. Browse and use them with a healthy dose complacency as to their importance. Knowing about the traits in Screens can certainly help you understand and contextualise a piece, but they will never capture the essence.
Having gotten a good grip on the system itself you may be wondering how it has all been put together. This section is for you. I will try to describe, without showing any code, how a Screens piece is constructed, from the placement of the screens, to the layering etc.
This section is not in any way necessary for appreciating the series, but if you are the curious type then you’ll get the most detailed description of the inner workings of the system (until someone reverse-engineers it and writes something better).
As discussed above, all screens are the result of 5 different actors that can be present or absent in a piece. The screens are generated one segment at a time with a segment length of 1. The length is of course arbitrary, but keeping it at unit length means that a lot of code can be trimmed down. For reference the viewport that the screens are drawn into is 100x141. Each actor is only responsible for making sure that its own screens aren’t placed too close to each other. For circular, square, and straight actors this is done by only allowing the start position (radius for circles, half-width for squares, distance to central line for straight) to lie at integer values (1, 2, 3, 4, …). Once a screen is placed that distance is no longer allowed. For b-spline and radial actors it is a bit different because the minimum distance between two screens can vary based on position and we can’t just rely and well-defined start positions. Thus, for these actors the screens are checked continuously against the current pool of screens as it grows and is terminated if it comes too close.
This rule has several benefits. It means that I don’t have to worry about intersections between screens from the same actor, it ensures a nice dispersed feel to the screens without feeling too ordered, and it removes some annoying artefacts in my rendering engine that couldn’t deal well with segments from different screens being too close to each other (reminiscent of z-fighting).
Drawing segments of circles, lines, squares, even b-splines, are not that hard and I won’t bore you with the details. The end result is that we end up with a bunch of segments of length 1. Some of these are connected in the ends and some are not. These segments are stored as a linked list meaning that I can traverse each screen while also being allowed to sort the pool of screens as I see fit.
But, back to where we are. We now have a bunch of lines, soon to become screens. Let’s have a look at the current situation:
Pretty boring, right? Well, we are only just getting started. Once we have all those lines we need to cut them (at least for the majority of pieces). This involves first and foremost figuring out which segments intersect with each other. Classic implementations of this problem uses a sweep-line algorithm to avoid comparing everything against everything, but I was a bit too lazy to be so sophisticated. In the end I made a pseudo sweep-line implementation where I sorted all segments along one axis based on it’s lowest end point and then compared each segment with the segments following. I then terminated the comparisons when the highest end of the first segment was below the lowest end of the next segment. This is pretty simple, code-wise, and fast enough for Screens (and Memories of Qilin 🙂) which is kind of the sweet spot for getting short code for ArtBlocks.
After the intersections have been detected one of the intersecting segments will be removed. Then the area around the cut will get pruned (meaning that the neighboring segments to the removed one is also removed). Lastly I remove screens that has become too short due to all the cutting and pruning. This is how it progresses:
The last part left is to rotate the lines slightly around the x-axis, tilting them slightly into the picture plane, giving the characteristic isometric perspective. The effect is very slight, but it basically compress everything a bit along the y-axis.
Now, up until this point we have only worked with line segments, and we are now ready to convert these to the screens we all know and love. This is quite simple as all it requires is to extrude the line downwards according to the height of the screen. That is, we make a copy of the line segment, move it downwards and connect the two segments into a parallelogram. Doing that, we get:
which is hardly what we expected. This look is largely due to the fact that we are simply drawing the outline of each screen, and all the screens outside the viewport are showing themselves because nothing is occluding them. If we fill all screens with white we can remove this:
Hmm… it’s still not right. It doesn’t resemble our pattern at all. The reason is that we are drawing each segment in the order it is created - not based on its location in space. Intuitively we want to draw the segments farthest away first so that they get correctly occluded by segments in front of them. While this seems simple in theory, sorting segments in a way so that no segment overlaps a segment coming after it is not trivial. In some cases it is fine just sorting by e.g. the lowest y-value in the segment, but it can easily break down when segments get close to each other. Consider each of these three examples. There is no single consistent way to sort all of them correctly by comparing the coordinates of the end points:
What we are dealing with is a 2D version of how to figure out a drawing order of triangles in 3D space so that those closest by is always drawn last. As you can imagine, this problem was pretty important for 3D games and I was inspired by the approach taken by John Carmack in the original Doom game, namely that of binary space partition (BSP) trees. In the simplest form, I take a root segment, and divide all other segments based on which side of the line supporting the root segment it lies. I then recursively do that until I have a binary tree. This tree can now be sorted based on which child lies on the visible or invisible side of their root line based on a given vantage point and you end up with a draw order:
We have now arrived at our destination in terms of figuring out the screens… on to the colors!
A splash of color
Colors are a big part of the screens series — both because the different palettes adds so much ambiance to the piece (hardly unique to Screens), but also because the coloring is integral to the rendering since it defines the layers. We already saw in the section on rendering that each color is rendered as a black and white layer, which then gets converted into color as it is applied to the master image. The rendering of this layer is without much fanfare. Each screen is assigned two colors for each of its sides. When rendering a layer for a specific color we look at which side of the small segment faces us and chose the two colors corresponding to that side. Then, if we are currently rendering a color not present in the two colors we paint it white. If the current colour matches the lightest of the two we paint it black. Lastly, if it matches the darkest of the two we paint it a shade of grey relative to the segments location along the screen. The end result for our current example is:
If we were to use these directly we would get this…
Now, while this is fun to look at it is just soo boring compared to the textured version, so how do we get there?
Texturing like a pro
The texture in screens is arguable the reason the whole series exists. While Screens is hardly just about texture, I started to design it because I wanted a venue for the texture in a long form format, having played with it in a more hand-held fashion in my Constructive series. So, what is this texture?
It leans heavily into how you would apply blue-noise dithering. This type of dithering uses a blue noise texture of the same size as your image (if you don’t know what blue noise it, just think of it as a fancier cousin of white noise) and for each pixel checks whether the source image value is higher or lower than that of the blue noise pixel. If it is higher you make the pixel white, if it is darker you make it black. In the plot below you can see the noise as the gray background curve. The higher the curve the lighter the pixel value. The gradient is then the line cutting through it diagonally from pure dark in the lower left corner, to pure white in the upper right corner. We can then see that everywhere the gradient line is below the curve we get a black color and everywhere it is above we get a white color and this will end up as a binary approximation of the gradient.
Now, there are two issues with using blue noise dithering. First, aesthetically I didn’t want a pixel level dithering. I wanted my grains to have dimensions and shape. Second, blue noise takes forever to generate at high resolution (we are talking hours).
However, high-frequency simplex noise have a lot of the same characteristics as blue noise, can be generated on demand in a shader, and is resolution independent. So, we simply use that instead…
We see that we substitute the peculiarly pleasant, but also artificially looking pattern from the blue noise, with something much more organic looking from the simplex noise. And, as stated above, the grain created by simplex noise can be rendered at any size while blue noise is forever confined to the size of a pixel.
There are a bit more to the texture used in Screens than that, but those are technicalities. I modify the simplex noise in slight ways to make it a bit more organic and give it some macro features, and if splotches are on I set some areas to 1 and some to zero based on thresholding another simplex noise of lower frequency.
In the end this is how I transform those clean screens shown above, into the grainy, messy, joy that you know and love from the project. And with that last technicality we arrive at the final piece:
So, we arrive at our final destination. The last words have been finally said (from me, at least), about the provenance, context, and technical side of Screens. I am thoroughly thrilled that so many people have taken this series to heart and finds joy browsing the collection, perhaps even buying a piece for themselves. There is no greater privilege as an artist than to be allowed some room inside the consciousness of others and I can’t thank you enough ❤️