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.

Here's the fragment shader.

#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

enter image description here

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

enter image description here

What went wrong?


1 Answer 1


This line doesn't look quite right:

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.)

  • $\begingroup$ lol this is what happens when you stop programming for a couple of years :-) thanks for idiot-checking me $\endgroup$
    – spraff
    Commented Feb 20, 2018 at 8:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.