# What's wrong with my computation of the intersection of a ray with a sphere

I am learning GLSL and trying to raytrace a sphere.

Here is a fragment shader. It correctly discards fragments which are not on the sphere, but when I try to calculate the point of intersection (and hence, the normal), I get nonsense.

#version 300 es
precision mediump float;
out mediump vec4 out_colour;

in  mediump vec3 X;      // intersection of ray with polygon

uniform mediump vec3 C;  // camera position
uniform mediump vec3 CS; // sphere position - camera position
uniform         float r; // sphere radius

void main ()
{
vec3 CX = X - C;

// |t.CX-CS|=r, CX.CX.t.t - 2.CS.CX.t + CS.CS - r.r = 0

float a = dot (CX, CX);
float b = -2.0 * dot (CX, CS);
float c = dot (CS, CS) - r * r;

float det = b * b - 4.0 * a * c;

if (det < 0.0)

float t = (-b - sqrt (det)) / 2.0 * a;

if (t <= 0.0)

vec3 N = normalize (t * CX - CS);

out_colour = vec4 (N, 1);
}


Here's an illustration of the variable names

I was expecting the normals to be illustrated with a wide-ranging rgb colour across the sphere, but as you can see...

What went wrong?

float t = (-b - sqrt (det)) / 2.0 * a;

You're missing parentheses around (2.0 * a). Remember that multiplication and division have equal operator precedence, so the expression as it's currently written means ((-b - sqrt (det)) / 2.0) * a, putting the a in the numerator instead of the denominator.
(Oh and this is a nitpick, but the thing you named det is called a “discriminant”, not a determinant.)