【GLSL】色付きのオブジェクト
See the Pen objects with color by aadebdeb (@aadebdeb) on CodePen.
#define PI 3.14159265359 #define TWO_PI PI * 2.0 #define HALF_PI PI / 2.0 precision mediump float; uniform float u_time; uniform vec2 u_mouse; uniform vec2 u_resolution; struct Camera { vec3 position; vec3 ray; }; float random(float v) { return fract(sin(v) * 43758.5453123); } float smoothmin(float d1, float d2, float k) { return -log(exp(-k * d1) + exp(-k * d2)) / k; } vec3 repeat(vec3 p, vec3 interval) { return mod(p, interval) - interval / 2.0; } vec3 repeatX(vec3 p, float interval) { return vec3(mod(p.x, interval) - interval / 2.0, p.y, p.z); } vec3 repeatY(vec3 p, float interval) { return vec3(p.x, mod(p.y, interval) - interval / 2.0, p.z); } vec3 repeatZ(vec3 p, float interval) { return vec3(p.x, p.y, mod(p.z, interval) - interval / 2.0); } vec3 rotateX(vec3 p, float theta) { float c = cos(-theta); float s = sin(-theta); mat3 m = mat3(vec3(1, 0.0, 0.0), vec3(0.0, c, -s), vec3(0.0, s, c)); return m * p; } vec3 rotateY(vec3 p, float theta) { float c = cos(-theta); float s = sin(-theta); mat3 m = mat3(vec3(c, 0.0, s), vec3(0.0, 1.0, 0.0), vec3(-s, 0.0, c)); return m * p; } vec3 rotateZ(vec3 p, float theta) { float c = cos(-theta); float s = sin(-theta); mat3 m = mat3(vec3(c, -s, 0.0), vec3(s, c, 0.0), vec3(0.0, 0.0, 1.0)); return m * p; } vec3 translate(vec3 p, vec3 t) { mat4 m = mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(-t.x, -t.y, -t.z, 1.0)); return (m * vec4(p, 1.0)).xyz; } float calcBoxDistance(vec3 p, vec3 size) { return length(max(abs(p) - size, 0.0)); } float calcRoundBoxDistance(vec3 p, vec3 size, float r) { return calcBoxDistance(p, size) - r; } float calcSphereDistance(vec3 p, float size) { return length(p) - size; } float calcPlainDistance(vec3 p, vec3 n) { return dot(p, n); } float calcTorusDistance(vec3 p, vec2 size) { vec2 q = vec2(length(p.xz) - size.x, p.y); return length(q) - size.y; } float calcCylinderDistance(vec3 p, vec3 size) { return length(p.xz - size.xy) - size.z; } float calcDistance(vec3 p) { float d = 10000000.0; d = min(d, calcSphereDistance(translate(p, vec3(-1.0, 0.0, 0.0)), 0.4)); d = min(d, calcSphereDistance(translate(p, vec3(0.0, 0.0, 0.0)), 0.4)); d = min(d, calcSphereDistance(translate(p, vec3(1.0, 0.0, 0.0)), 0.4)); 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)) )); } vec3 calcColor(vec3 p) { vec4 cd = vec4(vec3(1.0), 1000000.0); float d; d = calcSphereDistance(translate(p, vec3(-1.0, 0.0, 0.0)), 0.4); cd = d < cd.w ? vec4(1.0, 0.0, 0.0, d) : cd; d = calcSphereDistance(translate(p, vec3(0.0, 0.0, 0.0)), 0.4); cd = d < cd.w ? vec4(0.0, 1.0, 0.0, d) : cd; d = calcSphereDistance(translate(p, vec3(1.0, 0.0, 0.0)), 0.4); cd = d < cd.w ? vec4(0.0, 0.0, 1.0, d) : cd; return vec3(cd.x, cd.y, cd.z); } Camera getPerspectiveCamera(vec2 pos, vec3 eye, vec3 center, vec3 top, float fov) { float camRadian = fov / 2.0 * PI / 180.0; vec3 viewDir = normalize(center - eye); vec3 camSide = cross(viewDir, top); vec3 camTop = cross(camSide, viewDir); Camera camera; camera.position = eye; camera.ray = normalize(camTop * sin(camRadian * pos.y) + camSide * sin(camRadian * pos.x) + viewDir * cos(camRadian * pos.x)); return camera; } Camera getOrthographicCamera(vec2 pos, vec3 eye, vec3 center, vec3 top, float width, float height) { vec3 viewDir = normalize(center - eye); vec3 camSide = cross(viewDir, top); vec3 camTop = cross(camSide, viewDir); Camera camera; camera.position = eye + vec3(camTop * pos.y * height / 2.0 + camSide * pos.x * width / 2.0); camera.ray = viewDir; return camera; } void main(void) { vec2 st = (gl_FragCoord.xy * 2.0 - u_resolution) / min(u_resolution.x, u_resolution.y); vec2 mouse = (u_mouse * 2.0 - u_resolution) / min(u_resolution.x, u_resolution.y); vec3 cameraPosition = vec3(mouse.x * 3.0, mouse.y * 3.0, 3.0); vec3 viewCenter = vec3(0.0); vec3 cameraTop = vec3(0.0, 1.0, 0.0); Camera camera = getPerspectiveCamera(st, cameraPosition, viewCenter, vec3(0.0, 1.0, 0.0), 60.0); // Camera camera = getOrthographicCamera(st, cameraPosition, viewCenter, vec3(0.0, 1.0, 0.0), 50.0, 50.0); vec3 rayPosition = camera.position; vec3 rayDirection = camera.ray; float radian = u_time * 0.0003; vec3 lightPosition = vec3(20.0, 20.0, 20.0); vec3 color = vec3(0.0); float d; for (int i = 0; i < 64; i++) { d = calcDistance(rayPosition); rayPosition += rayDirection * d; } if (d < 0.0001) { vec3 normal = calcNormal(rayPosition); vec3 vecToLight = normalize(lightPosition - rayPosition); float diffuseWeight = max(dot(normal, vecToLight), 0.0); vec3 reflectVec = normalize(reflect(-vecToLight, normal)); float specularWeight = pow(max(dot(reflectVec, -rayDirection), 0.0), 16.0); vec3 c = calcColor(rayPosition); color = c * (vec3(0.2, 0.2, 0.2) + vec3(0.7, 0.7, 0.7) * diffuseWeight) + vec3(1.0, 1.0, 1.0) * specularWeight; } gl_FragColor = vec4(color, 1.0); }