第 6 课:Ray-sphere intersection
实现
uniform vec2 iResolution;
const vec3 sphereCenter = vec3(0.0, 0.0, -5.0);
const float sphereRadius = 2.0;
const vec3 sphereColor = vec3(0.8, 0.3, 0.3);
const vec3 rayOrigin = vec3(0.0, 0.0, 3.0);
float sphereIntersect(
vec3 rayOrigin,
vec3 rayDir,
vec3 sphereCenter,
float sphereRadius
) {
vec3 L = rayOrigin - sphereCenter;
float a = 1.0;
float b = 2.0 * dot(L, rayDir);
float c = dot(L, L) - sphereRadius * sphereRadius;
float D = b * b - 4.0 * a * c;
if (D < 0.0) return 0.0;
return min(-b - sqrt(D), (-b + sqrt(D))) / (2.0 * a);
}
void main() {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
uv = (uv * 2.0) - 1.0;
uv.x *= iResolution.x / iResolution.y;
vec3 imagePlanePixel = vec3(uv.x, uv.y, 0.0);
vec3 rayDir = normalize(imagePlanePixel - rayOrigin);
float t = sphereIntersect(
rayOrigin,
rayDir,
sphereCenter,
sphereRadius
);
vec3 hitPoint = rayOrigin + rayDir * t;
t = clamp(t, 0.0, 1.0);
gl_FragColor = vec4(sphereColor * t, 1.0);
}