How did it get converted into 1 line of code from 3 lines? Remapping uv and fixing aspect ratio in shaders

52 Views Asked by At

How would you get from this

vec2 uv = fragCoord/iResolution.xy; // <0, 1>
uv -= 0.5; // <-0.5,0.5>
uv.x *= iResolution.x/iResolution.y; // fix aspect ratio

to this?

vec2 uv = (fragCoord - .5 * iResolution.xy) / iResolution.y; // Condense 3 lines down to a single line!

Well, I tried breaking it down into components

((fragCoord.x-0.5) / iResolution.x) * (iResolution.x / iResolution.y)

((fragCoord.y-0.5) / iResolution.y)

1

There are 1 best solutions below

0
On BEST ANSWER

Let's add a 4th line:

vec2 uv = fragCoord/iResolution.xy;
uv -= 0.5;
uv.x *= iResolution.x/iResolution.y;
uv.y *= iResolution.y/iResolution.y;

Notice that iResolution.y/iResolution.y == 1, so the line we added changes nothing. However, it opens the possibility to simplify the code. We can now combine the 3rd and the 4th line by operating on two-component vectors:

vec2 uv = fragCoord/iResolution.xy;
uv -= 0.5;
uv *= iResolution.xy/iResolution.y;

Combining it all together into one algebraic expression turns it into:

vec2 uv = (fragCoord/iResolution.xy - 0.5)*iResolution.xy/iResolution.y;

Now we can move iResolution.xy inside the parentheses (distributive law of multiplication):

vec2 uv = (fragCoord/iResolution.xy*iResolution.xy - 0.5*iResolution.xy)/iResolution.y;

And, of course, dividing fragCoord by iResolution.xy cancels out with multiplying it by iResolution.xy, so we arrive at the one liner you had:

vec2 uv = (fragCoord - 0.5*iResolution.xy)/iResolution.y;