--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); }