1

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)

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • Why would you need to? Other than "harder to read", which is the opposite of useful, what problem with the three lines does the one-liner solve? – Mike 'Pomax' Kamermans May 15 '23 at 17:52
  • I'm just curious how it got compressed into 1 line. Well, one-liner uses one division less. (which I think is good?) – Artyom Chernyaev May 15 '23 at 17:59
  • It didn't, they do different things. The three lines fix the aspect ratio by scaling only `x` at the end, the one-liner scales the entire vec2 based on `y` so it changes _both_ `x` and `y`, with `y` becoming 1. – Mike 'Pomax' Kamermans May 15 '23 at 18:52
  • 1
    @Mike'Pomax'Kamermans That's actually not true. Both snippets are equivalent. See the derivation in my answer. – Yakov Galka Jun 10 '23 at 02:13

1 Answers1

2

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;
Yakov Galka
  • 70,775
  • 16
  • 139
  • 220