【GLSL】カメラを回転させる
See the Pen camera rotation 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;
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 calcSphereDistance(vec3 p, float size) {
return length(p) - size;
}
float calcDistance(vec3 p) {
float d = 100000.0;
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
d = min(d, calcSphereDistance(translate(p, vec3(float(x) , 0.0, float(y))), 0.3));
}
}
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);
vec2 mouse = (u_mouse * 2.0 - u_resolution) / min(u_resolution.x, u_resolution.y);
float time = u_time * 0.001;
float cameraRadius = 5.0;
vec3 cameraPosition = vec3(cameraRadius * cos(time), 5.0, cameraRadius * sin(time));
vec3 viewCenter = vec3(mouse.x, 0.0, mouse.y);
vec3 viewDirection = normalize(viewCenter - cameraPosition);
float fov = 60.0;
float angle = fov / 2.0 * PI / 180.0;
vec3 cameraTop = vec3(0.0, 1.0, 0.0);
vec3 cameraSide = cross(viewDirection, cameraTop);
vec3 rayDirection = normalize(cameraSide * sin(angle * st.x) + cameraTop * sin(angle * st.y) + viewDirection * cos(angle * st.x));
vec3 rayPosition = cameraPosition;
float radian = u_time * 0.0003;
vec3 lightPosition = vec3(5.0, 5.0, 5.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);
float weight = dot(normal, normalize(lightPosition));
color = vec3(1.0) * max(weight, 0.0) + vec3(0.1);
}
gl_FragColor = vec4(color, 1.0);
}