Layered Rendering with Framebuffers
Sometimes, in a sketch, you might want to draw something to an image instead of directly to the screen. This lets you use the image as a texture on 3D shapes, repeat the image multiple times efficiently, read the image's data when drawing something else, and more.
In 2D mode, you can use createGraphics() to achieve this. While they also work in WebGL mode, for better performance and more features, you can use createFramebuffer().
What makes Framebuffers special?
Framebuffers live on your computer's GPU (Graphics Processing Unit), the part of your computer that specializes in drawing pixels of images as fast as possible in parallel. This means you can write to and read from Framebuffers really quickly, without your computer having to move lots of data around!
Framebuffers also can contain more information than a typical image or canvas. You can use higher-precision floating point numbers to store colors, letting you do more without running into weird visuals from rounding errors. They can also store 3D depth information about the contents drawn on them, which can help you create visual effects like blurs and shadows.
Using Framebuffers
Framebuffers are like drawing targets. By calling .begin() on one, anything you draw will start going onto it instead of the main canvas. Calling .end() will make the main canvas be the draw target again, and you can then reference the framebuffer like an image.
Sketching with Feedback
Video feedback is a technique where the previous frame of a video gets used when drawing the next frame. This can look similar to when you stand between two mirrors.
To do this in a sketch, you typically draw to a layer so you have an image of the current frame. Then, when drawing to the next frame, you can add the previous frame to your drawing by using the image of the previous frame.
The fastest way to do this is to keep two layers around: one for the previous frame, and one for the next frame. At the start of draw(), swap the two layers so you can keep the image of the preview frame, clear the next frame, and draw a new image to it.
Framebuffers are especially good for feedback because they can store images as higher precision floating-point numbers, which you can specify with createFramebuffer({ format: FLOAT }). Normally, the red, green, and blue values of colors are stored as integers between 0-255. Each time you draw an image, the colors get rounded into that range, and a source frame can get drawn and redrawn many times in a feedback sketch, accumulating lots of rounding errors. That problem goes away when you use floats!
Sketching with Depth
When you draw to a Framebuffer, in addition to recording the color of the pixels, you are also recording their depth in space, stored as a number between 0 and 1. You can read this into a shader by looking at the depth property of a Framebuffer.
This can be useful if you want to change an image based on how far from the camera things are. One common effect that uses this is fog, where farther away objects are tinted more and more towards a fog color.
If you want to customize how close or far to the camera an object needs to be to get depth values of 0 or 1, specify near and far values in perspective().
Conclusion
If you're sketching in WebGL mode and need to draw to an image, consider using createFramebuffer() as a way to make your sketch run fast and give everyone the best viewing experience possible.
We hope the new techniques Framebuffers make possible inspire you and that you create art using them!