loremIpsum1771
loremIpsum1771

Reputation: 2527

Ray Tracer not rendering sphere properly

I've written a ray tracer in glsl that is supposed to diffusely shade a sphere (which in this case is actually just a 2D shape made from four vertices) but when the code runs I'm seeing both the outline of the sphere and the square that contains it instead of just the sphere. I very new to ray tracing so I'm just trying to get the hang of how this works. Here are some images of what it looks like (I added functionality for making it react when the cursor is moved within the sphere)

enter image description here enter image description here

What could be the cause of this? Here is some of the relevant code from the fragment shader:

float raySphere(vec3 V, vec3 W, vec4 sph) {
    float r = 1.0;
    float b = 2.0* dot(V,W);
    float c = dot(V, V) - (sph.w * sph.w);
    float h = b*b - 4.0*c;
    float t = (-b - sqrt(h))/2.0;
    if(h <0.0  || t < 0.0 ) return 10000.;
    return t;
   }

   // Diffusely shade a sphere.
   //    point is the x,y,z position of the surface point.
   //    sphere is the x,y,z,r definition of the sphere.
   //    material is the r,g,b color of the sphere.
   vec3 shadeSphere(vec3 point, vec4 sphere, vec3 material) {
      vec3 color = vec3(0.,0.,0.);
      vec3 N = (point - sphere.xyz) / sphere.w;
      float diffuse = max(dot(Ldir, N), 0.0);
      vec3 ambient = material/5.0;
      color = ambient + Lrgb * diffuse *  max(0.0, dot(N , Ldir));
      return color;
   }

   void main(void) {
      vec2 c = uCursor.xy;
      Lrgb = vec3(2.,3.5,4.0);
      Ldir = normalize(vec3(c.x, c.y, 1. - 2. * dot(c, c)));
      float x = vPosition.x;
      float y = vPosition.y;
      float z = computeZ(vPosition.xy, 1.0);
      // COMPUTE V AND W TO CREATE THE RAY FOR THIS PIXEL,
      // USING vPosition.x AND vPosition.y.
      vec2 uv = vPosition.xy/uCursor.xy;

      //generate a ray 
      vec3 V, W;
      //V  = vec3(0.0,1.0,0.0);
      //W = normalize(vec3( 2.0,0.0,1.0 ));

      V = vec3(0.0, 1.0, 3.0);
      W = normalize(vec3((-1.0 + 2.0  )*vec2(1.78,1.0), -1.0));

      //SET x,y,z AND r FOR sphere.

      sphere = vec4(x,y,z,V + W);

      //SET r,g,b FOR material.

      vec3 color = vec3(5., 2., 3.);
      float t = raySphere(V, W, sphere);
      if (t < 10000.)
         color = shadeSphere(V + t * W, sphere, material);
      //color.r = 0.7; 

      color = pow(color, vec3(.45,.45,.45)); // Do Gamma correction.

      gl_FragColor = vec4(color, 1.);        // Set opacity to 1.
   }

Upvotes: 0

Views: 244

Answers (1)

Miloslaw Smyk
Miloslaw Smyk

Reputation: 1323

The way raySphere() reports a miss (-1) together with how you check for hit in main() (t < 10000.) are not getting along.

Upvotes: 1

Related Questions