デモシーン10作目

デモシーン

10作目です。

このコードだけでこの動画のようになります。


#define PI 3.14159265359
#define lightDir normalize(vec3(1.0, 1.0, -1.0))
#define sphereRadius .1

float sdSphere(vec3 p, float r)              //球
{
    return length(p) - r;
}
float sdCappedCylinder( vec3 p, vec2 h )    //円柱
{
  vec2 d = abs(vec2(length(p.xz),p.y)) - h;
  return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}
float sdTorus( vec3 p, vec2 t )             //トーラス(ドーナツ)
{
  vec2 q = vec2(length(p.xz)-t.x,p.y);
  return length(q)-t.y;
}


float map(vec3 p){
    float d = 3.0;
    vec3 q = p;
    //torus
    d = min(d, sdTorus(q - vec3(0.0, 1.0, 0.0), vec2((2.0 + 0.5 * sin(iTime * PI)), .1)));
    //cylinder
    for (int i = 0; i < 10; i++) {
        float radius = 2.0 - float(i) * (0.1 * sin(iTime) + 0.15);
        float delta = 0.05 * (0.8 + 0.2 * sin(iTime * PI));
        float height = .1;
        if (i % 2 == 0) {
            float cylinder = sdCappedCylinder(q - vec3(0.0, -2.0, 0.0), vec2(radius, height));
            d = min(d, cylinder);
        } else {
            float cylinder = sdCappedCylinder(q - vec3(0.0, -2.0, 0.0) - vec3(0.0,0.1,0.0), vec2(radius, height));
            d = max(d, -cylinder);
        }
    }
    return d;
}


vec3 calcNormal( in vec3 pos )
{
    const float ep = 0.0001;
    vec2 e = vec2(1.0,-1.0)*0.5773;
    return normalize( e.xyy*map( pos + e.xyy*ep ) + 
					  e.yyx*map( pos + e.yyx*ep ) + 
					  e.yxy*map( pos + e.yxy*ep ) + 
					  e.xxx*map( pos + e.xxx*ep ) );
}

float calcSoftshadow( in vec3 ro, in vec3 rd, float tmin, float tmax, const float k )
{
	float res = 1.0;
    float t = tmin;
    for( int i=0; i<50; i++ )
    {
		float h = map( ro + rd*t );
        res = min( res, k*h/t );
        t += clamp( h, 0.02, 0.20 );
        if( res<0.005 || t>tmax ) break;
    }
    return clamp( res, 0.0, 1.0 );
}

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

void mainImage(out vec4 fragColor, in vec2 fragCoord){
    vec2 uv = fragCoord/iResolution.xy;
    uv = uv * 2.0 - 1.0;
    uv.x *= iResolution.x/iResolution.y;
    vec2 m = (iMouse.xy * 2.0 - iResolution.xy)/iResolution.xy;

    vec3 ro = vec3(0.0, 0.0, 4.);
    vec3 rd = normalize(vec3(uv, -1.0));
    vec3 col = vec3(0.0);
    vec3 totalCol = vec3(0.0);


    // 球の表面にカメラを配置
    vec3 spherePos = vec3(sin(iTime), 2. * cos((iTime + .5)) + 1., cos(iTime));

    ro.xz *= rot(iTime * PI / 4.);
    rd.xz *= rot(iTime * PI / 4.);

    ro.xz *= rot(-m.x);
    rd.xz *= rot(-m.x);

    ro.yz *= rot(-m.y);
    rd.yz *= rot(-m.y);



    float t = 0.0;
    for(int i = 0; i < 64; i++){
        vec3 p = ro + rd * t;
        float sphere = sdSphere(p - spherePos, sphereRadius);
        float d = map(p);
        d = min(d, sphere);
        if(d < 0.01 || t > 20.0) {           
            vec3 pos = ro + t*rd;
            vec3 nor = calcNormal(pos);   //法線
            vec3  lig = lightDir;  //光源の方向
            float dif = clamp(dot(nor,lig),0.0,1.0);    //拡散反射
            float sha = calcSoftshadow( pos, lig, 0.001, 1.0, 32.0 );   //影
            float amb = 0.5 + 0.5*nor.y;    //環境光

            if(d == sphere){
                col = vec3(t * .05);
                col +=  (
                        vec3(0.05,0.1,0.15)*amb + 
                        vec3(1.00,0.9,0.0)*dif*sha
                        );
                col = sqrt(col);
                col *= vec3(1.0, 0.8, 0.6);
            }
            else{
            col = vec3(t * .05);

            col +=  vec3(0.05,0.1,0.15)*amb + 
                    vec3(1.00,0.9,0.80)*dif*sha;
            col = sqrt(col);
            }

            totalCol += col;

            break;
        }
        t += d;
    }    

    fragColor = vec4(totalCol, 1.0);
}

制作を続けていきます。では。

#デジタルアート #デモシーン #3DCG #シェーダーコーディング #レイマーチング #SF #demoscene

Please follow and like us:

Follow me!

コメント

Social Share Buttons and Icons powered by Ultimatelysocial
YouTube
YouTube
Instagram
Copy link
URL has been copied successfully!
PAGE TOP