Daily Creative Coding

元「30 min. Processing」。毎日、Creative Codingします。

【GLSL】変形するボックス

See the Pen morphing box by aadebdeb (@aadebdeb) on CodePen.

#define PI 3.14159265359
#define TWO_PI PI * 2.0


precision mediump float;

uniform float u_time;
uniform vec2 u_mouse;
uniform vec2 u_resolution;

float calcBoxDistance(vec3 p, vec3 size) {
    return length(max(abs(p) - size, 0.0));
}

float calcDistance(vec3 p) {
    float t = u_time * 0.0004;
    float x = (sin(t) + 1.0) / 2.0 * 0.2;
    float y = (sin(t * 3.0) + 1.0) / 2.0 * 0.2;
    float z = (sin(t * 7.0) + 1.0) / 2.0 * 0.2;
    vec3 size = vec3(x, y, z);
    float d = calcBoxDistance(p, size);
    return d;
}

vec3 calcNormal(vec3 p) {
    float delta = 0.00001;
    return normalize(vec3(
        calcDistance(p + vec3(delta, 0.0, 0.0)) - calcDistance(p - vec3(delta, 0.0, 0.0)),
        calcDistance(p + vec3(0.0, delta, 0.0)) - calcDistance(p - vec3(0.0, delta, 0.0)),
        calcDistance(p + vec3(0.0, 0.0, delta)) - calcDistance(p - vec3(0.0, 0.0, delta))
    ));
}

void main(void) {
    vec2 st = (gl_FragCoord.xy * 2.0 - u_resolution) / min(u_resolution.x, u_resolution.y);

    vec3 cameraPosition = vec3(3.0, 3.0, 3.0);
    vec3 rayDirection = normalize(vec3(st, 0.0) - cameraPosition);
    vec3 rayPosition = cameraPosition;
    float radian = u_time * 0.0003;
    vec3 lightPositionR = vec3(10.0 * sin(radian), sin(radian) * 10.0, 10.0 * cos(radian));
    vec3 lightPositionG = vec3(10.0 * sin(radian * 3.0), 10.0, sin(radian) * 10.0 * cos(radian * 3.0));
    vec3 lightPositionB = vec3(10.0 * sin(radian * 5.0), 10.0, sin(radian) * 10.0 * cos(radian * 5.0));
    vec3 color = vec3(0.0);
    for (int i = 0; i < 16; i++) {
        float d = calcDistance(rayPosition);
        if (d < 0.0001) {
            vec3 normal = calcNormal(rayPosition);
            float weightR = dot(normal, normalize(lightPositionR));
            float weightG = dot(normal, normalize(lightPositionG));
            float weightB = dot(normal, normalize(lightPositionB));
            color = vec3(1.0, 0.0, 0.0) * max(weightR, 0.0)
                  + vec3(0.0, 1.0, 0.0) * max(weightG, 0.0)
                  + vec3(0.0, 0.0, 1.0) * max(weightB, 0.0)
                  + vec3(0.1);
            break;
        }
        rayPosition += rayDirection * d;
    }
    gl_FragColor = vec4(color, 1.0);
}
f:id:aa_debdeb:20170426094945p:plain