テラByteの時代にキロByte

shader又はdemosceneに関係する事

--shader(GLSL)の小技 01-- なるべく短くraymarching

最近、jsdo.itが繋がりにくくなり、今まで書き溜めたモノが簡単に見れなくなりました。 ちょっと、不便なので、ここに移す事にしました。せっかくなので、少し解説を付けたりしてみようと思います。 それと、今まで集めたり、作ったりしてモノも纏めてみようと思ってます。

なるべく短くraymarching

raymarchingの手法は、だいぶ浸透してきたみたいなので説明は省きます。 このshaderの説明だけにします。 最近はwebGL2.0も浸透してきたみたいなので、このブログで書くスクリプトは全て#version 300 esになります。 これは、for()文でconstを使わずに済み、bit演算が出来ます。あと、switchかな。 これができると、とても便利です。
このスクリプトはraymarchingで3Dのオブジェを表現する最低ラインだと思います。見た感じ使ってない変数も入ってますけど、後で利用したいところがあるので、最低限だけは、書いてます。 iの使い方が特殊ですけど、それを説明します。 iは、疑似AOとして利用しています。 普通の処理だと、rayがオブジェクトに衝突するまでに要する回数をmaxのスッテプ数で割る奴です。 1.0 - 衝突するまでに要する回数/maxスッテプ数 それを、こういう書き方をしてます。
https://www.shadertoy.com/view/ltBSRy ここより入手したスキルです。

for(i=1.0;i>0.0;i-=1./50.0)

この50.0はステップ数になります。
まあ、これで3Dの表現はできるので、これから始めていきます。 これに、カメラを使ったり、回転させてり、色を付けたり、距離関数でモデルを作ったりと、表現を増やしていくだけです。

今回のshader (shadertoy rule)

float map(vec3 p)
{
    return length(p)-1.0;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv=(fragCoord*2.0-iResolution.xy)/iResolution.y;
    vec3 ro=vec3(0,0,-3);
    vec3 rd=normalize(vec3(uv,2));
    float d,i,t=0.0;
    vec3 p=ro;
    vec3 col=vec3(0);
    for(i=1.0;i>0.0;i-=1./50.0)
    {
        t+=d=map(p);
        if(d<0.001)
        {
            col+=i*i*i;
            break;
        }
        p+=rd*d;
    }
    fragColor=vec4(col,1.0);
}