--shader(GLSL)の小技 11-- rayの勢いを抑えて中途半端な距離を利用する
今回の奴は最近みつけたスキルです。 ネーミング的にはゴーストなんて呼ぶのが良いかななんて思ってます。
使用例として
vec3 col=vec3(0); for(i=1.0;i>0.0;i-=1./30.0) { t+=d=map(p)*(0.2*sin(iTime)+0.6); if(d<0.001) { if(uv.y>0.0) col+=i*i; break; } p+=rd*d; } if(uv.x>0.0) col += vec3(1,0,0)*exp(-d*d*5.0);
画面の上半分は、rayが衝突した時の描写です。if(uv.y>0.0) col+=i*i;
画面の右半分は、raymarchig loopを抜けたあと距離を使って2D描写のようにしたもの。 if(uv.x>0.0) col += vec3(1,0,0)*exp(-d*d*5.0);
ちょっと実験的に書いてます。
このraymarchig loopは30回
と通常より少なく設定して、t+=d=map(p)*(0.2*sin(iTime)+0.6);
とmap関数に1以下の定数をかけ、わざとrayを衝突しないようにしています。
ここでの狙いは、衝突してないけど近くにいる距離をつくることで、2D描写のスキルを使ってオーラのような表現をつくることです。
loop回数とか,map関数の距離とかのチューニングで、わりとアナログなノリで絵を出すスキルです。
今回のshader (shadertoy rule)
mat2 rotate(float a) { return mat2(cos(a),sin(a),-sin(a),cos(a)); } float deLineBox(vec3 p) { p.xy*=rotate(iTime*0.5); p.yz*=rotate(iTime*0.5); float de = 1e9; p = abs(p)-0.6; for(int i=0; i<3;i++) { vec3 q =p; q[i]=max(0.0,q[i]); de= min(de,length(q)-0.02); } return de; } float map(vec3 p) { return deLineBox(p); } void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv=(fragCoord*2.0-iResolution.xy)/iResolution.y; vec3 ro=vec3(0,0,-2); vec3 rd=normalize(vec3(uv,2)); vec3 ta=vec3(0); vec3 w=normalize(ta-ro); vec3 u=normalize(cross(w,vec3(0,1,0))); vec3 v=cross(u,w); mat3 lookat=mat3(u,v,w); rd=lookat*rd; float d,i,t=0.0; vec3 p=ro; vec3 col=vec3(0); for(i=1.0;i>0.0;i-=1./30.0) { t+=d=map(p)*(0.2*sin(iTime)+0.6); if(d<0.001) { if(uv.y>0.0) col+=i*i; break; } p+=rd*d; } if(uv.x>0.0) col += vec3(1,0,0)*exp(-d*d*5.0); fragColor=vec4(col,1.0); }