Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[Manta] r1926 - trunk/Engine/Shadows


Chronological Thread 
  • From: arobison@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [Manta] r1926 - trunk/Engine/Shadows
  • Date: Wed, 12 Dec 2007 23:17:54 -0700 (MST)

Author: arobison
Date: Wed Dec 12 23:17:53 2007
New Revision: 1926

Modified:
   trunk/Engine/Shadows/HardShadows.cc
Log:
A work in progress for fixing attenuating shadows.  The old code ignored minT 
values on the
shadow rays which made area lights not shadow correctly (the shadow rays 
would intersect
with the area light geometry).  This fix is still a little buggy, but the 
visual artifacts
from the area light intersections are gone, now there's some something weird 
happening
in the umbras of attenuated shadows.


Modified: trunk/Engine/Shadows/HardShadows.cc
==============================================================================
--- trunk/Engine/Shadows/HardShadows.cc (original)
+++ trunk/Engine/Shadows/HardShadows.cc Wed Dec 12 23:17:53 2007
@@ -196,16 +196,28 @@
   // Send the shadow rays, if any
   if(last != -1){
     shadowRays.resize ( first, last + 1);
+
+    // We need to save the original distances before the rays are cast into 
the scene again.
+    Packet<Real> distance_left;
+    if(attenuateShadows) {
+      for(int i = shadowRays.begin(); i < shadowRays.end(); ++i) {
+        distance_left.set(i, shadowRays.getMinT(i));
+      } 
+    }
+
+    // Cast shadow rays
     context.scene->getObject()->intersect(context, shadowRays);
+
+    // And attenuate if required
     if (attenuateShadows) {
       bool raysActive;
       Real cutoff = context.scene->getRenderParameters().importanceCutoff;
       int currentDepth = shadowRays.getDepth();
       int maxDepth = context.scene->getRenderParameters().maxDepth;
       int pass = 0;
-      bool rayAttenudated[RayPacket::MaxSize];
+      bool rayAttenuated[RayPacket::MaxSize];
       for(int i = shadowRays.begin(); i < shadowRays.end(); ++i) {
-        rayAttenudated[i] = false;
+        rayAttenuated[i] = false;
       }
       do {
         pass++;
@@ -213,6 +225,7 @@
         // Those rays that did hit something, we need to compute the
         // attenuation.
 
+        // Compute the attenuation of the shadow rays.
         // This is when none of the rays hit, we can avoid the loop below.
         bool anyHit = false;
         for(int i = shadowRays.begin();i<shadowRays.end();){
@@ -220,10 +233,10 @@
           const Material* hit_matl = shadowRays.getHitMaterial(i);
           if(shadowRays.wasHit(i) && !shadowRays.rayIsMasked(i)){
             anyHit = true;
-            rayAttenudated[i] = true;
+            rayAttenuated[i] = true;
             while(end < shadowRays.end() && shadowRays.wasHit(end) &&
                   shadowRays.getHitMaterial(end) == hit_matl) {
-              rayAttenudated[end] = true;
+              rayAttenuated[end] = true;
               end++;
             }
             RayPacket subPacket(shadowRays, i, end);
@@ -233,46 +246,45 @@
           i=end;
         }
 
+        // Propagate shadow rays through surfaces, attenuating along the way.
         raysActive = false;
         if (anyHit) {
           // If there are any rays left that have attenuation, create a
           // new shadow ray and keep it going.
           for(int i = shadowRays.begin();i<shadowRays.end();){
             int end = i+1;
-            if(rayAttenudated[i]) {
+            if(rayAttenuated[i]) {
               if (shadowRays.getColor(i).luminance() > cutoff) {
                 if (!raysActive) {
                   raysActive = true;
                   currentDepth++;
                 }
                 while(end < shadowRays.end() &&
-                      rayAttenudated[i] &&
+                      rayAttenuated[end] &&
                       (shadowRays.getColor(end).luminance() > cutoff))
                   end++;
-                // Change all the origins and reset the hits?
+                // Change all the origins and reset the hits
                 RayPacket subPacket(shadowRays, i, end);
                 subPacket.setDepth(currentDepth);
                 subPacket.computeHitPositions();
-                subPacket.resetHits();
                 for(int s_index = subPacket.begin(); s_index < 
subPacket.end();
                     ++s_index) {
+                  subPacket.setHitMaterial(s_index, NULL);
                   subPacket.setOrigin(s_index, 
subPacket.getHitPosition(s_index));
+                  Real new_distance = distance_left.get(i) - 
subPacket.getMinT(i);
+                  subPacket.overrideMinT(i, new_distance);
+                  distance_left.set(i, new_distance);
                 }
                 context.scene->getObject()->intersect(context, subPacket);
               } else {
-                // The ray has reached its saturation point, masked it off
-                rayAttenudated[i] = false;
-                shadowRays.resetHit(i);
+                // The ray has reached its saturation point, mask it off
+                rayAttenuated[i] = false;
               }
             }
             i=end;
           } // end foreach (shadowRay)
         } // if (anyHit)
       } while (raysActive && (currentDepth < maxDepth));
-      for(int i = shadowRays.begin(); i < shadowRays.end(); ++i) {
-        if (rayAttenudated[i])
-          shadowRays.resetHit(i);
-      }
     }
   }
 




  • [Manta] r1926 - trunk/Engine/Shadows, arobison, 12/13/2007

Archive powered by MHonArc 2.6.16.

Top of page