Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[Manta] r2045 - trunk/Model/Primitives


Chronological Thread 
  • From: "Thiago Ize" <thiago@sci.utah.edu>
  • To: manta@sci.utah.edu
  • Subject: [Manta] r2045 - trunk/Model/Primitives
  • Date: Sun, 10 Feb 2008 23:04:57 -0700 (MST)

Author: thiago
Date: Sun Feb 10 23:04:56 2008
New Revision: 2045

Modified:
   trunk/Model/Primitives/Sphere.cc
Log:
Removed an old #ifdef'd out sphere intersection code that
wouldn't even compile and replaced it with another #ifdef'd
out version that is more robust to the self intersection
that causes surface acne. This is a bit slower since it has
to do a few more adds, multiplies, and branches (still just
one sqrt, which is the dominant cost), but in the
default manta scene it's slower by only a few percent. If
people like this, then this can be converted to SSE and the
specialized cases.

Modified: trunk/Model/Primitives/Sphere.cc
==============================================================================
--- trunk/Model/Primitives/Sphere.cc    (original)
+++ trunk/Model/Primitives/Sphere.cc    Sun Feb 10 23:04:56 2008
@@ -50,32 +50,36 @@
 
 void Sphere::intersect(const RenderContext&, RayPacket& rays) const
 {
-#if VERSION1
-  rays.normalizeDirections();
-  for(int i = 0;i<rays.getSize();i++){
-    RayPacket::Element& e = rays.get(i);
-    Vector OC=center-e.ray.origin();
-    Real tca=Dot(OC, e.ray.direction());
-    Real l2oc=OC.length2();
-    Real rad2=radius*radius;
-    if(l2oc <= rad2){
-      // Inside the sphere
-      Real t2hc=rad2-l2oc+tca*tca;
-      Real thc=Sqrt(t2hc);
-      Real t=tca+thc;
-      e.hitInfo.hit(t, getMaterial(), this, getTexCoordMapper());
-    } else {
-      if(tca < 0){
-        // Behind ray, no intersections...
-      } else {
-        Real t2hc=rad2-l2oc+tca*tca;
-        if(t2hc <= 0){
-          // Ray misses, no intersections
-        } else {
-          Real thc=Sqrt(t2hc);
-          e.hitInfo.hit(tca-thc, getMaterial(), this, getTexCoordMapper());
-          e.hitInfo.hit(tca+thc, getMaterial(), this, getTexCoordMapper());
-        }
+#if 0
+  //This version will find a t value close to the actual value
+  //(actually finds the midpoint between the two intersections), and
+  //then uses that initial t to cast a ray from there in order to get
+  //a more exact t value. This is more robust and allows for a smaller
+  //T_EPSILON.
+  for(int i = rays.begin();i<rays.end();i++){
+    Vector O(rays.getOrigin(i)-center);
+    const Vector D(rays.getDirection(i));
+    const Real A = Dot(D, D);
+    const Real A_inv = static_cast<Real>(1)/A;
+    Real B = Dot(O, D);
+    Real C = Dot(O, O) - radius*radius;
+    Real disc = B*B-A*C;
+    if(disc >= 0){
+      Real t = -B*A_inv; //average of two t intersections.
+      O += D*t;
+      Real B = Dot(O, D);
+      Real C = Dot(O, O) - radius*radius;
+      disc = B*B-A*C;
+
+      if (disc >= 0) {
+        const Real r = Sqrt(disc);
+        const Real t1 = t + -(r+B)*A_inv;
+        if (t1 <= T_EPSILON)
+          t += (r-B)*A_inv;
+        else
+          t = t1;
+
+        rays.hit(i, t, getMaterial(), this, getTexCoordMapper());
       }
     }
   }




  • [Manta] r2045 - trunk/Model/Primitives, Thiago Ize, 02/11/2008

Archive powered by MHonArc 2.6.16.

Top of page