Remapping Ranges
Task
Use remapping to build the pixel color from its uv coordinates:
- red is
0.0atuv.x = 0.25and grows to1.0atuv.x = 0.75(left of0.25the red is0.0, right of0.75it is full - the screen does this for you); - green is
1.0at the bottom of the screen and0.0at the top; - blue is
0.0, alpha is1.0.
Hint 1
Red: which uv.x should give 0.0? Subtract it, and the range starts at zero. How wide is the range? Divide by the width, and it ends at one.
Hint 2
Check your formula at the edges: at uv.x = 0.25 it must give 0.0, at 0.75 - 1.0, and halfway, at 0.5, - 0.5.
Hint 3
Green goes the other way: 1.0 at the bottom, 0.0 at the top. Look for the reversed range in the table of common remaps.
Theory
Values often come in one range, but you need them in another:
uvgoes from0to1, but you want0in the center of the screen and-1/1at the edges;- a wave goes from
-1to1, but a color must be from0to1; - you want a gradient only between
x = 0.25andx = 0.75, not across the whole screen.
Converting a value from one range to another is called remapping. It needs nothing but subtraction, division, multiplication and addition.
From any range to 0..1
To turn x from the range [a, b] into [0, 1]:
- subtract the start,
x - a: now the range starts at0and goes tob - a; - divide by the length,
(x - a) / (b - a): now it ends at1.
// x from 0.25 to 0.75 -> t from 0.0 to 1.0
float t = (uv.x - 0.25) / (0.75 - 0.25);
Drag a and b and watch the line: it crosses 0 at a and 1 at b.
::plot[f="(x - a) / (b - a)", a=0.25 0..1, b=0.75 0..1, y=-0.5..1.5]
Outside [a, b] the result keeps going: below 0 left of a, above 1 right of b. The screen shows every value below 0 as black and every value above 1 as full brightness, so for colors that's often just what you want. Later you'll learn functions that cut these values off exactly where you need.
From 0..1 to any range
The other way around: multiply by the new length, then add the new start.
// t from 0.0 to 1.0 -> from -1.0 to 1.0
float centered = t * 2.0 - 1.0;
Common remaps
| From | To | Code |
|---|---|---|
0..1 |
-1..1 |
x * 2.0 - 1.0 |
-1..1 |
0..1 |
x * 0.5 + 0.5 |
0..1 |
1..0 (reversed) |
1.0 - x |
0..1 |
-0.5..0.5 (centered) |
x - 0.5 |
a..b |
0..1 |
(x - a) / (b - a) |
It works on vectors too: uv * 2.0 - 1.0 remaps both x and y, so the center of the screen becomes (0.0, 0.0). You'll use this in almost every shader.