Loops
Task
The starter has two arrays:
rects- 4 rectangles inuvcoordinates. Each is avec4(HLSL:float4):xandyare its bottom-left corner,zandwits top-right corner;colors- the color of each rectangle:colors[i]belongs torects[i].
Use a loop to draw all four rectangles on a black background. They overlap: draw them in order, so a later rectangle covers the earlier ones, like sheets of paper put on a table one after another.
Hint 1
One pass of the loop handles one rectangle, rects[i]. A pixel is inside it when its uv is to the right of and above the bottom-left corner and to the left of and below the top-right corner.
Hint 2
Create the color variable before the loop (black). Inside the loop, change it only when the pixel is inside the current rectangle. Because the loop goes from the first rectangle to the last, the last one that covers the pixel wins.
Hint 3
Write the result to the output after the loop, not inside it.
Theory
A loop runs the same code several times. Instead of writing the code for 5 rectangles 5 times, you write it once and repeat it.
The for loop
for (int i = 0; i < 5; i++) {
// this code runs 5 times: with i = 0, 1, 2, 3, 4
}
The brackets after for have three parts, separated by ;:
int i = 0- runs once, before the loop: creates the counteri;i < 5- checked before every repeat: the loop goes on while it'strue;i++- runs after every repeat: adds1toi(the same asi = i + 1).
Collecting a result
A loop usually builds up a value step by step. Create the variable before the loop and update it inside:
float sum = 0.0;
for (int i = 0; i < 4; i++) {
sum += 0.25; // the same as sum = sum + 0.25
}
// sum is 1.0
Besides += there are -=, *= and /=.
Loops and arrays
The counter is an int, so it's a ready-made array index:
for (int i = 0; i < 3; i++) {
vec3 c = palette[i]; // palette[0], palette[1], palette[2]
}
If you need the counter in a calculation with floats, convert it: float(i).
Leaving early
break stops the loop right away; continue skips the rest of the current repeat and goes to the next one:
for (int i = 0; i < 100; i++) {
if (sum > 1.0) {
break;
}
sum += 0.3;
}
There's also a while (condition) { ... } loop, but for is the one you'll see in shaders most of the time.
Loops on the GPU
Remember that the shader runs for every pixel: a loop of 100 repeats on a Full HD screen is 200 million repeats per frame. Keep loops short, and prefer a fixed number of repeats (a number or a const, not a value that changes from pixel to pixel), so the compiler can plan them.
HLSL
The for loop, break, continue, += and int(...) / float(...) look exactly the same in HLSL.