テラByteの時代にキロByte

shader又はdemosceneに関係する事

--shader(GLSL)の小技 12-- 3Dプロットをしてみる

これは、raymarchingでは、ありません。

float dePoint(vec3 ro, vec3 rd, vec3 a)
float deLine(vec3 ro, vec3 rd, vec3 a, in vec3 b)
float deCircle(vec3 ro, vec3 rd, vec3 p, vec3 n, float r)

rayの原点、rayのベクトル、位置座標等を使い、距離を導き、2D描写と同じ要領で絵を出します。
上手く説明できないので、使い方をソースに書いておきました。
マクロを書いておいたので、3Dプロットのツールとして使えます。 以前書いた文字も同居できるので、一緒に使うと、解りやすいと思います。
これも、やり方次第では、raymarchingと同居できます。

Shader - Shadertoy BETA に、これを使ったshaderを上げたら、以前からあったスキルらしく Shader - Shadertoy BETA を教わりました。

neort.io

こういうモノも作れます。

今回のshader (shadertoy rule)

mat2 rotate(float a)
{
    return mat2(cos(a),sin(a),-sin(a),cos(a));
}

float dePoint(vec3 ro, vec3 rd, vec3 a)
{
    return length(cross(a-ro, rd));
}

float deLine(vec3 ro, vec3 rd, vec3 a, in vec3 b)
{
    vec3 ab =normalize(b-a),ao = a-ro;
    float d0 = dot(rd, ab), d1 = dot(rd, ao), d2 = dot(ab, ao);
    float len = (d0*d1-d2)/(1.0-d0*d0);
    len= clamp(len,0.0,length(b-a));
    vec3 p = a+ab*len;
    return length(cross(p-ro, rd));
}


float deCircle(vec3 ro, vec3 rd, vec3 p, vec3 n, float r)
{
    float de = 1e10;
    vec3 u = normalize(cross(rd,n));
    vec3 v = cross(u,n);
    vec3 q = dot(p-ro,n)/dot(rd,n)*rd+ro;    
    float g = min(r,dot(u,q-p));
    float h = sqrt(r*r-g*g);
    vec3 a = u*g+p;    
    de = min(de, length(cross(a+v*h-ro, rd)));
    de = min(de, length(cross(a-v*h-ro, rd)));
    a = normalize(q-p)*r+p ;
    de = min(de,length(cross(a-ro, rd)));
    a = rd*dot(p-ro,rd)+ro-p;   
    a = normalize(cross(cross(n,a),n));
    a = a*r+p;
    de = min(de, length(cross(a-ro, rd)));
    return de;        
}

#define PNT(a,c) de=dePoint(ro,rd,a);\
    col = mix(c,col,smoothstep(0.08,0.1,de));
#define LIN(a,b,c) de=deLine(ro, rd, a, b);\
    col = mix(c, col, smoothstep(0.0,0.05,de));
#define CIR(a,n,r,c) de=deCircle(ro,rd,a,n,r);\
    col = mix(c,col,smoothstep(0.0,0.03,de));


void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv=(fragCoord*2.0-iResolution.xy)/iResolution.y;
    vec3 ro=vec3(0,2,-8);
    ro.zx*=rotate(iTime*0.5);
    vec3 rd=normalize(vec3(uv,2));
    vec3 w=normalize(-ro);
    vec3 u=normalize(cross(w,vec3(0,1,0)));
    rd=mat3(u,cross(u,w),w)*normalize(vec3(uv,2));
    
    vec3 col=vec3(0);
    
    vec3 o = vec3(0.5,0.3,-5);
    vec3 p = vec3(0,0,0);
    vec3 d = normalize(vec3(0.2,0.3,1));
    vec3 a = o + d * dot(p - o, d);
    vec3 x = cross(p - o, d);
    vec3 y = cross(x, d);
    
    float de;
    // LIN(点a、点b、色) 線の描写
    LIN(o, o + d * 5.0, vec3(0,0,1))
    LIN(p, p + x, vec3(1,0.5,0))
    LIN(p, p + y, vec3(0,1,0))
    
    // CIR(原点、円の法線、半径、色) 円の描写
    CIR(p,d, length(cross(p - o, d)), vec3(1,1,0))
    
    // PNT(点、色) 点の描写
    PNT(a, vec3(1,1,0))
    PNT(o, vec3(1,1,1))
    PNT(p, vec3(1,0,0))
        
    fragColor=vec4(col,1.0);
}