Your first rendering pipeline
Now it's time to set up your first rendering pipeline! In this guide, we'll walk you through the process of creating a simple rendering pipeline using the p5.asciify
library. We'll cover the following steps:
- Setting up and configuring a simple rendering pipeline through the
setupAsciify()
function. - Updating properties of the rendering pipeline during the draw loop.
- Applying a filter to the ASCII representation drawn to the main canvas using the
drawAsciify()
function.
Setting up the brightness-based ASCII conversion renderer
Looking back at the first snippet given in the Introduction
section, we saw that the p5.asciify
library applied ASCII conversion to the main canvas by default without using any functions provided by p5.asciify
, just plain p5.js
code.
Now, let's start introducing the setupAsciify()
function to this sketch to set up and customize the already pre-enabled brightness-based ASCII conversion renderer to our liking.
In comparison to the previous snippet, we added two new variables and a new function setupAsciify()
to the sketch:
-
asciifier
- This variable will hold the reference to the
P5Asciifier
object that is provided by default through thep5asciify
object, allowing us to manage the rendering pipeline and its renderers.
- This variable will hold the reference to the
-
brightnessRenderer
- This variable will hold the reference to a brightness-based
P5AsciifyBrightnessRenderer
, which is part of theasciifier
s rendering pipeline.
- This variable will hold the reference to a brightness-based
In setupAsciify()
, which is called automatically once at the beginning of the sketch after the p5.js setup()
function, we fetch the relevant objects we want to use throughout the sketch and store them in the variables we created earlier.
Using asciifier.fontSize(number);
, we can set the font size for all renderers in the pipeline.
During setupAsciify()
, make sure to store all relevant references to P5Asciifier
and it's P5AsciifyRenderer
objects in variables so you can access them later in the draw()
loop or other functions without having to search for them in potentially larger lists of renderers every time you need them.
The asciifier
object also provides a lot of other functions and properties to manage the rendering pipeline, such as asciifier.font(p5.Font);
to set the font for all renderers in the pipeline. Make sure to check the P5Asciifier API documentation
for more information on the available functions and properties.
Adding the edge detection-based ASCII conversion renderer on top
Right now, the sketch only uses the brightness-based ASCII conversion renderer. Let's add an edge detection-based ASCII conversion renderer on top of it to create a more complex rendering pipeline.
We can do this by enabling the pre-defined "edge"
renderer in the asciifier
object and setting its properties to our liking.
The set up is similar to the previous one, but now we have two renderers in the pipeline: the brightness-based and the edge detection-based renderer. Since the edge detection-based renderer is executed after the brightness-based one, it will be drawn on top of the ASCII representation of the texture generated by the brightness-based renderer. If the order was reversed, the edges wouldn't be visible, as they would be drawn behind the all covering brightness-based renderer.
Drawing on top of the ASCII representation
Since p5.asciify
encapsulates everything that happens in the draw()
loop, we need to use the drawAsciify()
function to draw on top of the ASCII representation that is being rendered to the main canvas. This function is called automatically once per frame after the ASCII representation is drawn to the main canvas.
In this sketch, we use the drawAsciify()
function to apply an inversion filter to the main canvas, which is done using the p5.js
function filter(INVERT);
. This will invert the colors of the ASCII representation, making it look like a negative image.
You can use drawAsciify()
similarly to the draw()
function in p5.js
, so there are no limitations on what you can do with it. Since we are in a WebGL
context, we could also apply the asciified texture to a 3D shape using texture(asciifier.texture);
and box();
, for example. This way, you can create complex 3D scenes with ASCII representations of textures applied to them.
Updating properties during runtime
Since we just learned that p5.asciify
encapsulates everything that happens in the draw()
loop, with the ASCII representation being generated and drawn to the main canvas afterwards, it makes sense to update the properties of the rendering pipeline during the draw()
loop to see the changes in the frame that's rendered next. Changes to the properties being done in the drawAsciify()
function will be applied to the frame after the one being rendered at the moment.
Besides updating the properties by calling a renderers update()
function, where we can pass any number of properties to update, we can also call individual functions like .enabled(boolean)
or .flipVertically(boolean)
to update the properties of the renderer.
That's it for this guide! You now know how to set up a simple rendering pipeline using the p5.asciify
library and some of it's pre-defined renderers. You also learned how to draw on top of the ASCII representation and update properties of the rendering pipeline during runtime. We've only scratched the surface here with those examples, so feel free to experiment with the code and try out different combinations of renderers and properties to create your own unique ASCII art!