This document is a guide and example to help you write useful tutorial outlines. Your outline should capture the essential points of a tutorial and help get productive peer reviews early on.
The example below drafts a skeleton for a written tutorial. For videos, you can use nested bullet lists instead of headings and use common abbreviations and other shorthands.
In my experience, writing outlines first facilitates collaboration, and it can save hours of work.
It also allows you to:
Getting straight to writing instead can lead to messy lessons that introduce topics and new techniques in a sub-optimal order.
I recommend starting with a summary of your topic, target audience, and goals. Flesh it out or rework it as you prepare code examples or experiment with the subject matter.
texture(TEXTURE, UV + vec2(x_offset, y_offset))
smoothstep
to soften value transitions.These “techniques” here are the most essential or the new techniques introduced by the tutorial. They are vital points you want to nail and share with the student. This is useful to know when giving reviews, as they are areas you want to make as clear as possible. While you can go over the techniques explained previously faster.
The more detailed outline, like the example below, should always and only come after code reviews. This is because the tutorial’s content depends on the finished project. If the code needs to change after you wrote the tutorial, updating the content will waste a lot of your time that you could spend working on other projects instead.
For the outline, I directly create my document’s skeleton. The headings will be the same as in the final article. I also iterate over documents when writing, starting by writing the skeleton for sub-sections and main paragraphs.
You can put code, screenshots, and anything other than text in your outlines, when relevant, if it communicates the idea well. You can leave notes about pictures to add, for example, PICTURE: show the layers in the effect side-by-side
or PICTURE: code graph that shows how the three classes communicate via signals
.
Below, you will find the outline for a tutorial about creating a 2D stroke shader.
Examples of gameplay situations where this shader can be useful, like outlining collectibles or interactive objects on hover.
VIDEO: animated example of showing the outlines on mouse hover.
You will learn to:
texture(TEXTURE, UV + vec2(x_offset, y_offset))
smoothstep
to soften value transitions.Boil down the high-level steps to 1 or 2 paragraphs.
Create a material and a canvas item shader.
Add two uniforms, line_color
and line_thickness
Calculate the size of line_thickness
in UV space.
Introduce texture sampling with a UV offset.
Calculate 4 offset samples for the outline.
Sum them up and clamp the value to compute the outline mask.
Mix the sprite with the line_color
using the outline mask.
Use the Region section in the inspector to extend the sprite’s bbox. Use the TextureRegion editor in the bottom panel to resize the bbox interactively. Optimization note: doing so increases the rendered area. The renderer and the shader will process every pixel, including transparent pixels. That’s why, by default, the bbox fits the imported sprite and doesn’t leave an extra margin.
Our shader leaves gaps when objects have sharp angles due to the lack of samples. Add four samples offsetting diagonally. Update the sum and outline mask calculations. Show the final code.
Create the mask using a product instead of a sum.
float product = left * right * up * down * upper_left * upper_right * bottom_left * bottom_right;
float outline_inner = 1.0 - product;
COLOR = mix(color, line_color, outline);
This causes visual artifacts when the line_thickness
has a value below 1.0.
Introduce smoothstep
that uses Hermite interpolation, that is to say, an interpolation between two values with ease in and out around the extremities of the range.
Use smoothstep
to expand the outline mask and get rid of the unwanted aliased pixels.
float alpha = outline * smoothstep(color.a, 0.0, 0.05);
COLOR = mix(color, line_color, alpha);
PICTURE: black-and-white view of the inner outline mask.
Divide the offset’s size by two. We need to change the outer outline calculation to avoid overlapping values and visual artifacts in the final mask.
float stroke_outer = max(max(max(left, right), max(up, down)), max(max(upper_left, upper_right), max(bottom_right, bottom_left))) - color.a;
Add both the inner and outer mask to produce the final stroke. Show the final code and result.