Sunday, March 7, 2010

PostTwiceDaily2 03/07/2010 (p.m.)

  • tags: no_tag

    • Example Code


      The following C++ code snippet is an example how the simplified version of the ray/sphere intersection described above might be implemented. Note that it assumes the ray has already been transformed into object space, and be aware that the code below is not necessarily the most efficient implementation available!


      bool SpherePrimitive::intersect(const Ray& ray, float* t)
      {
      //Compute A, B and C coefficients
      float a = dot(ray.d, ray.d);
      float b = 2 * dot(ray.d, ray.o);
      float c = dot(ray.o, ray.o) - (r * r);

      //Find discriminant
      float disc = b * b - 4 * a * c;

      // if discriminant is negative there are no real roots, so return
      // false as ray misses sphere
      if (disc < 0)
      return false;

      // compute q as described above
      float distSqrt = sqrtf(disc);
      float q;
      if (b < 0)
      q = (-b - distSqrt)/2.0;
      else
      q = (-b + distSqrt)/2.0;

      // compute t0 and t1
      float t0 = q / a;
      float t1 = c / q;

      // make sure t0 is smaller than t1
      if (t0 > t1)
      {
      // if t0 is bigger than t1 swap them around
      float temp = t0;
      t0 = t1;
      t1 = temp;
      }

      // if t1 is less than zero, the object is in the ray's negative direction
      // and consequently the ray misses the sphere
      if (t1 < 0)
      return false;

      // if t0 is less than zero, the intersection point is at t1
      if (t0 < 0)
      {
      t = t1;
      return true;
      }
      // else the intersection point is at t0
      else
      {
      t = t0;
      return true;
      }
      }
  • tags: no_tag

    • Ray-Sphere Intersection



      Algebraic solution



      A ray is defined by: R(t) = R0 + t * Rd , t > 0 with R0 = [X0,
      Y0, Z0] and Rd = [Xd, Yd, Zd]



      A sphere can be defined by its center and radius with Sc = [xc, yc,
      zc] So a sphere of radius Sr is:





      S = the set of points[xs, ys, zs], where (xs - xc)2 + (ys - yc)2 + (zs - zc)2 = Sr2



      To solve algebraically, substitute the ray equation into sphere equation and solve for t.



      For ray:

      X = X0 + Xd * t

      Y = Y0 + Yd * t

      Z = Z0 + Zd * t



      putting X, Y, Z into the sphere equation for Xs, Ys, Zs



      (X0 + Xd * t - Xc)2 + (Y0 + Yd * t - Yc)2 + (Z0 + Zd * t - Zc)2 = Sr^2



      or A*t^2 + B*t + C = 0

      with: A = Xd^2 + Yd^2 + Zd^2

      B = 2 * (Xd * (X0 - Xc) + Yd * (Y0 - Yc) + Zd * (Z0 - Zc))

      C = (X0 - Xc)^2 + (Y0 - Yc)^2 + (Z0 - Zc)^2 - Sr^2



      Note: If |Rd| = 1 (normalized), then A = 1. So we can compute Sr^2 once.

      So with A = 1, the solution of the quadratic equation is



      t0, t1 = (- B + (B^2 - 4*C)^1/2) / 2 where t0 is for (-) and t1 is for (+)



      If the discriminant is < 0.0 then there is no real root and no
      intersection. If there is a real root (Disc. > = 0.0) then the smaller positive root is
      the closest intersection point. So we can just compute t0 and if it is positive, then we
      are done, else compute t1. The intersection point is:




      Ri = [xi, yi, zi] = [x0 + xd * ti , y0 + yd * ti, z0 + zd * ti]

      Unit N at surface
      SN = [(xi - xc)/Sr, (yi - yc)/Sr, (zi - zc)/Sr]
  • tags: no_tag

    • RayTrace is recursive, that is, it calls itself.


      Procedure RenderPicture()
      For each pixel on the screen,
      Generate a ray R from the viewing position through the point on the view
      plane corresponding to this pixel.
      Call the procedure RayTrace() with the arguments R and 0
      Plot the pixel in the colour value returned by RayTrace()
      Next pixel
      End Procedure

      Procedure RayTrace(ray R, integer Depth) returns colour
      Set the numerical variable Dis to a maximum value
      Set the object pointer Obj to null
      For each object in the scene
      Calculate the distance (from the starting point of R) of the nearest
      intersection of R with the object in the forward direction
      If this distance is less than Dis
      Update Dis to this distance
      Set Obj to point to this object
      End if
      Next object
      If Obj is not null
      Set the position variable Pt to the nearest intersection point of R and Obj
      Set the total colour C to black
      For each light source in the scene
      For each object in the scene
      If this object blocks the light coming from the light source to Pt
      Attenuate the intensity of the received light by the transmittivity
      of the object
      End if
      Next object
      Calculate the perceived colour of Obj at Pt due to this light source
      using the value of the attenuated light intensity
      Add this colour value to C
      Next light source
      If Depth is less than a maximum value
      Generate two rays Refl and Refr in the reflected and refracted directions,
      starting from Pt
      Call RayTrace with arguments Refl and Depth + 1
      Add (the return value * reflectivity of Obj) to C
      Call RayTrace with arguments Refr and Depth + 1
      Add (the return value * transmittivity of Obj) to C
      End if
      Else
      Set the total colour C to the background colour
      End if
      Return C
      End Procedure
  • tags: no_tag

    • We are only interested in ray/sphere intersection


      points that are in front of the viewer. This


      corresponds to situations in which t is positive.

      Does this mean strictly positive (t>0)? or (t>=0)?
    • When t=0, this means that the ray intersects the surface at the location of the eye. When the eye and the surface co-exist at the same point, the image will not be very interesting. Your view vector V will be undefined in that case, which can complicate the shading process. I would recommend to only consider intersection points for which t>0.




Posted from Diigo. The rest of my favorite links are here.