gl_FragCoordの正規化
解説/アルゴリズム
vec2 uv = (gl_FragCoord.xy * 2.0 - vResolution) / min(vResolution.x, vResolution.y);
gl_FragCoord はよくこの形で正規化されることが多い。
gl_FragCoord には Canvas のピクセル座標が格納されている。
ただし、y 座標は上に行くほど大きくなるので、左下が (0, 0) 、右上が (キャンバスの幅, キャンバスの高さ) になる。
この gl_FragCoord を クリップ空間と同じの -1.0 ~ 1.0 の範囲に正規化するのが目的となる。
まずは Canvas の縦横が同じサイズだった場合について考えてみる。
vec2 uv = gl_FragCoord.xy / vResolution * 2.0 - 1.0;
gl_FragCoord を Canvas のサイズで割ることで 0.0 ~ 1.0 の範囲に変換する。
この範囲を 2 倍することで、0.0 ~ 2.0 の範囲に変換する。
更にこの範囲から -1.0 を引くことで、 -1.0 ~ 1.0 の範囲に変換することができた。
次は Canvas の縦横が異なるサイズだった場合について考えてみる。
vec2 uv = gl_FragCoord.xy / vResolution.y;
縦横のサイズが異なる場合で縦横比を維持したい場合は、Canvas の幅か高さどちらか一方で割らなければならない。
ここでは高さで割ることにする。
vec2 uv = gl_FragCoord.xy / vResolution.y * 2.0 - vec2(vResolution.x / vResolution.y, 1.0);
vResolution.y で割って正規化する場合、縦のサイズは 1 だが、横は vResolution.x / vResolution.y となる。
なので、 -1.0
の部分を、vec2(vResolution.x / vResolution.y, 1.0)
にする必要がある。
各項の vResolution.y で割るところを括りだすと、
vec2 uv = (gl_FragCoord.xy * 2.0 - vec2(vResolution.x, vResolution.y)) / vResolution.y;
となり、 vec2(vResolution.x, vResolution.y)
はただの vResolution のことなので、
vec2 uv = (gl_FragCoord.xy * 2.0 - vResolution) / vResolution.y;
と書くことができる。