テラByteの時代にキロByte

shader又はdemosceneに関係する事

つぶやきGLSLで使ってるレイベクトル

つぶやきGLSLでraymarchingをする時に使ってるレイベクトルについて書いてみます。twiglのgeekest(300es)のフォーマットで話は進めます。
通常のレイベクトルは

normalize(vec3(((FC.xy*2.-r)/r.y),2))

と、だいたい2.0くらいを焦点距離にして作る。それをつぶやきGLSLでは手を抜いて

vec3(((FC.xy-.5*r)/r.y),1)

として運用している。正規化をしてないのだから画面中央から離れれば離れる程ベクトルのスカラーが大きくなるのは想像出来る。raymarchigのロジックからしても破綻してる。なのに解っていても、これを使う理由は一つ。短く書けるからだ。これをそのまま使うと画面の端にはアーティファクトが発生する。さて、どうするか?対処法としてSDFに重みを付ける。

sdf(p)*0.5

みたいな感じ。
一度、絵を出してみる。
通常の場合

normalize(vec3(((FC.xy*2.-.r)/r.y),2))

f:id:gaziya:20210722134551p:plain 正規化を外した場合

vec3((FC.xy*2.-r)/r.y,2)

f:id:gaziya:20210722135115p:plain 当然ヒドイ事になる。
次に焦点距離とuvの範囲を変えてみる。

vec3((FC.xy-.5*r)/r.y,1)

f:id:gaziya:20210722135503p:plain だいぶマシになった。ここでSDFに重みを付けてみる。この場合のSDFは

(length(p)-.3)*.7

f:id:gaziya:20210722140018p:plain これで使えるレベルまで来た。ちょっとアーティファクトがあるけど気になるなら重みを変えるだけ。
これをすると画面が暗くなるけど、違うところで調整すれば良い。
こんなトリックで成立している。フラクタルをするなら、必ず重みの調整がついてまわるので*.7は文字数の内に入らない。フラクタルの初期倍率は、1.0なのだが、それを2.0にするだけ。
更に美味しい話がある。
通常のraymarchingの進行は。(進んだ距離をgとした場合)

vec3 rd=normalize(vec3(((FC.xy*2.-r)/r.y),2);
vec3 ro=vec3(0,0,-5);
....
p=g*rd+ro;
...

つぶやきGLSLで書くなら

p=g*normalize(vec3(((FC.xy*2.-r)/r.y),2);
p.z-=5.;

これが、normalize()を使わないなら

p=vec3((FC.xy-.5*r)/r.y*g,g-5.)

これで済む。これで、かなりの文字数が削減された。つぶやきGLSLで、ここまでは読み切れないと思うので説明してみました。あくまでも、つぶやきGLSLの上のスキルと承知して使ってください。ループの中で毎回レイベクトルを生成してるし、画面中央部分のスッテプ回数は通常より多くなるので、コストパフォーマンスは悪過ぎです。文字数優先の為にこうなったけど本能的に受け付けないかも。自分も最初はGPU酷使には抵抗がありました。