Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[Manta] r2039 - in trunk: Engine/Shadows Interface Model/Groups Model/Primitives


Chronological Thread 
  • From: "Thiago Ize" <thiago@sci.utah.edu>
  • To: manta@sci.utah.edu
  • Subject: [Manta] r2039 - in trunk: Engine/Shadows Interface Model/Groups Model/Primitives
  • Date: Wed, 6 Feb 2008 23:31:27 -0700 (MST)

Author: thiago
Date: Wed Feb  6 23:31:26 2008
New Revision: 2039

Modified:
   trunk/Engine/Shadows/HardShadows.cc
   trunk/Interface/Parameters.h
   trunk/Model/Groups/KDTree.cc
   trunk/Model/Primitives/KenslerShirleyTriangle.cc
   trunk/Model/Primitives/WaldTriangle.cc
Log:
Engine/Shadows/HardShadows.cc:
  -instead of just masking invalid rays, we now set those
   rays to contain valid directions and origins. This way
   those invalid rays won't mess up other acceleration
   structures or primitives. For instance, calculating a
   bounding frustum over a packet that contains invalid
   rays would result in a frustum that is much bigger than
   it should be. This also removes a lot of valgrinds warnings.


Model/Primitives/KenslerShirleyTriangle.cc
Model/Primitives/WaldTriangle.cc:
  -Fix bug where intersection tests would occur on rays that
   were not valid. This occurs because sse_begin can be > than
   sse_end if there is no sse section (this has been previously
   fixed in other parts of manta, but some parts still need 
   this fixes).

Model/Groups/KDTree.cc:
  -Don't need to normalize directions. Not doing this of course
   gives a slight speedup :)

Interface/Parameters.h
  -T_EPSILON was set to 1e-3 which is too big for most normal
    scenes. This was the cause for DynBVH not displaying shadows,
    while the kdtree, which was normalizing rays, did display shadows.


Modified: trunk/Engine/Shadows/HardShadows.cc
==============================================================================
--- trunk/Engine/Shadows/HardShadows.cc (original)
+++ trunk/Engine/Shadows/HardShadows.cc Wed Feb  6 23:31:26 2008
@@ -99,7 +99,23 @@
           last = i;
           if (first < 0)
             first = i;
-        } else {
+        }
+        else if (first >= 0) {
+          //if we've already found a valid ray, use that to copy valid
+          //data into the invalid ray.
+          shadowRays.setOrigin(i, shadowRays.getOrigin(first));
+          shadowRays.setDirection(i, shadowRays.getDirection(first));
+          shadowRays.setTime(i, shadowRays.getTime(first));
+
+          shadowRays.maskRay(i); //this sets minT -MAXT and hitMatl to -1
+          //We set minT to 0 instead of -MAXT just in case an algorithm
+          //uses the ray hit position to compute things. In which case
+          //having the hit position at the origin would probably break
+          //things less than having it be infinitely far away in the
+          //negative direction.
+          shadowRays.overrideMinT(i, 0);//TOOD: verify 0 is ok (should we 
use -eps?).
+        }
+        else {
           shadowRays.maskRay(i);
         }
       }
@@ -115,6 +131,21 @@
           last = i;
           if (first < 0)
             first = i;
+        }
+        else if (first >= 0) {
+          //if we've already found a valid ray, use that to copy valid
+          //data into the invalid ray.
+          shadowRays.setOrigin(i, shadowRays.getOrigin(first));
+          shadowRays.setDirection(i, shadowRays.getDirection(first));
+          shadowRays.setTime(i, shadowRays.getTime(first));
+
+          shadowRays.maskRay(i); //this sets minT -MAXT and hitMatl to -1
+          //We set minT to 0 instead of -MAXT just in case an algorithm
+          //uses the ray hit position to compute things. In which case
+          //having the hit position at the origin would probably break
+          //things less than having it be infinitely far away in the
+          //negative direction.
+          shadowRays.overrideMinT(i, 0);//TOOD: verify 0 is ok (should we 
use -eps?).
         } else {
           shadowRays.maskRay(i);
         }
@@ -122,6 +153,9 @@
 
       RayPacketData* sourceData = sourceRays.data;
       RayPacketData* shadowData = shadowRays.data;
+      sse_t validOx=set4(0), validOy=set4(0), validOz=set4(0);
+      sse_t validDx=set4(0), validDy=set4(0), validDz=set4(0);
+      sse_t validTimes;
       for(;i<e;i+=4){
         __m128 normalx = _mm_load_ps(&sourceData->ffnormal[0][i]);
         __m128 normaly = _mm_load_ps(&sourceData->ffnormal[1][i]);
@@ -142,18 +176,66 @@
         _mm_store_ps((float*)&shadowData->minT[i],
                      _mm_or_ps(_mm_andnot_ps(mask,
                                              
_mm_load_ps((float*)&shadowData->minT[i])),
-                               _mm_and_ps(mask, _mm_set1_ps(-MAXT))));
-
-        _mm_store_ps(&shadowData->origin[0][i], 
_mm_load_ps(&sourceData->hitPosition[0][i]));
-        _mm_store_ps(&shadowData->origin[1][i], 
_mm_load_ps(&sourceData->hitPosition[1][i]));
-        _mm_store_ps(&shadowData->origin[2][i], 
_mm_load_ps(&sourceData->hitPosition[2][i]));
+                               _mm_and_ps(mask, _mm_setzero_ps())));
 
-        _mm_store_ps(&shadowData->time[i], 
_mm_load_ps(&sourceData->time[i]));
-
-        if(_mm_movemask_ps(mask) != 0xf){
+        const int maskResults = getmask4(mask);
+        if(maskResults != 0xf){
           last = i+3;
-          if (first < 0)
+          if (first < 0) {
             first = i;
+
+            if (maskResults == 0) {
+              validOx = load44(&sourceData->hitPosition[0][i]);
+              validOy = load44(&sourceData->hitPosition[1][i]);
+              validOz = load44(&sourceData->hitPosition[2][i]);
+
+              validDx = dx;
+              validDy = dy;
+              validDz = dz;
+
+              validTimes = load44(&sourceData->time[i]);
+            }
+            else {
+              for (int r=0; r < 4; r++) {
+                if ( ((maskResults>>r)&1) == 0 ) { //r is valid
+                  validOx = set4(sourceData->hitPosition[0][i+r]);
+                  validOy = set4(sourceData->hitPosition[1][i+r]);
+                  validOz = set4(sourceData->hitPosition[2][i+r]);
+
+                  validDx = set4(sourceData->direction[0][i+r]);
+                  validDy = set4(sourceData->direction[0][i+r]);
+                  validDz = set4(sourceData->direction[0][i+r]);
+
+                  validTimes = set4(sourceData->time[i+r]);
+                  
+                  break;
+                }
+              }
+            }
+          }
+        }
+
+        if (maskResults == 0) {
+          store44(&shadowData->origin[0][i], 
load44(&sourceData->hitPosition[0][i]));
+          store44(&shadowData->origin[1][i], 
load44(&sourceData->hitPosition[1][i]));
+          store44(&shadowData->origin[2][i], 
load44(&sourceData->hitPosition[2][i]));
+
+          store44(&shadowData->time[i], load44(&sourceData->time[i]));
+        }
+        else if (first >= 0){
+          store44(&shadowData->origin[0][i], 
+                  masknot4(mask, load44(&sourceData->hitPosition[0][i]), 
validOx));
+          store44(&shadowData->origin[1][i],
+                  masknot4(mask, load44(&sourceData->hitPosition[1][i]), 
validOy));
+          store44(&shadowData->origin[2][i],
+                  masknot4(mask, load44(&sourceData->hitPosition[2][i]), 
validOz));
+
+          store44(&shadowData->direction[0][i], masknot4(mask, dx, validDx));
+          store44(&shadowData->direction[1][i], masknot4(mask, dy, validDy));
+          store44(&shadowData->direction[2][i], masknot4(mask, dz, validDz));
+
+          store44(&shadowData->time[i],
+                  masknot4(mask, load44(&sourceData->time[i]), validTimes));
         }
       }
 
@@ -167,7 +249,23 @@
           last = i;
           if (first < 0)
             first = i;
-        } else {
+        }
+        else if (first >= 0) {
+          //if we've already found a valid ray, use that to copy valid
+          //data into the invalid ray.
+          shadowRays.setOrigin(i, shadowRays.getOrigin(first));
+          shadowRays.setDirection(i, shadowRays.getDirection(first));
+          shadowRays.setTime(i, shadowRays.getTime(first));
+
+          shadowRays.maskRay(i); //this sets minT -MAXT and hitMatl to -1
+          //We set minT to 0 instead of -MAXT just in case an algorithm
+          //uses the ray hit position to compute things. In which case
+          //having the hit position at the origin would probably break
+          //things less than having it be infinitely far away in the
+          //negative direction.
+          shadowRays.overrideMinT(i, 0);//TOOD: verify 0 is ok (should we 
use -eps?).
+        }
+        else {
           shadowRays.maskRay(i);
         }
       }
@@ -185,9 +283,24 @@
         last = i;
         if (first < 0)
           first = i;
-      } else {
-        shadowRays.maskRay(i);
+      } 
+      else if (first >= 0) {
+        //if we've already found a valid ray, use that to copy valid
+        //data into the invalid ray.
+        shadowRays.setOrigin(i, shadowRays.getOrigin(first));
+        shadowRays.setDirection(i, shadowRays.getDirection(first));
+        shadowRays.setTime(i, shadowRays.getTime(first));
+        
+        shadowRays.maskRay(i); //this sets minT -MAXT and hitMatl to -1
+        //We set minT to 0 instead of -MAXT just in case an algorithm
+        //uses the ray hit position to compute things. In which case
+        //having the hit position at the origin would probably break
+        //things less than having it be infinitely far away in the
+        //negative direction.
+        shadowRays.overrideMinT(i, 0);//TOOD: verify 0 is ok (should we use 
-eps?).
       }
+      else
+        shadowRays.maskRay(i);
     }
 #endif // ifdef MANTA_SSE
     j++;

Modified: trunk/Interface/Parameters.h
==============================================================================
--- trunk/Interface/Parameters.h        (original)
+++ trunk/Interface/Parameters.h        Wed Feb  6 23:31:26 2008
@@ -30,7 +30,7 @@
 #define Manta_Interface_Parameters_h
 
 #define MAXCACHELINESIZE 128
-#define T_EPSILON ((Real)1.e-3)
+#define T_EPSILON ((Real)1.e-5)
 #define DENOM_EPSILON ((Real)1.e-6)
 #define COLOR_EPSILON ((Real)1.e-4)
 #define MAXT ((Real)1.e19)

Modified: trunk/Model/Groups/KDTree.cc
==============================================================================
--- trunk/Model/Groups/KDTree.cc        (original)
+++ trunk/Model/Groups/KDTree.cc        Wed Feb  6 23:31:26 2008
@@ -328,7 +328,6 @@
 
 void KDTree::intersect(const RenderContext& context, RayPacket& rays) const
 {
-  rays.normalizeDirections();
   rays.computeSigns();
   rays.computeInverseDirections();
 

Modified: trunk/Model/Primitives/KenslerShirleyTriangle.cc
==============================================================================
--- trunk/Model/Primitives/KenslerShirleyTriangle.cc    (original)
+++ trunk/Model/Primitives/KenslerShirleyTriangle.cc    Wed Feb  6 23:31:26 
2008
@@ -103,6 +103,46 @@
   const int sse_begin = ( ray_begin + 3 ) & ( ~3 );
   const int sse_end   = ( ray_end ) & ( ~3 );
 
+  if (sse_begin >= sse_end) { //no sse section exists.
+    const unsigned int index = myID*3;
+    const Vector p0 = mesh->vertices[mesh->vertex_indices[index+0]];
+    const Vector p1 = mesh->vertices[mesh->vertex_indices[index+1]];
+    const Vector p2 = mesh->vertices[mesh->vertex_indices[index+2]];
+
+    const Vector edge0 = p1 - p0;
+    const Vector edge1 = p0 - p2;
+    const Vector normal = Cross( edge0, edge1 );
+    for ( int ray = ray_begin; ray < ray_end; ++ray ) {
+      const Vector o = Vector( data->origin[ 0 ][ ray ],
+                               data->origin[ 1 ][ ray ],
+                               data->origin[ 2 ][ ray ] );
+      const float oldt = data->minT[ ray ];
+      const Vector d = Vector( data->direction[ 0 ][ ray ],
+                               data->direction[ 1 ][ ray ],
+                               data->direction[ 2 ][ ray ] );
+      const float rcp = 1.0f / Dot( normal, d );
+      const Vector edge2 = p0 - o;
+      const float toverd = Dot( normal, edge2 ) * rcp;
+      if ( toverd > oldt - T_EPSILON ||
+           toverd < T_EPSILON )
+        continue;
+      const Vector interm = Cross( edge2, d );
+      const float uoverd = Dot( interm, edge1 ) * rcp;
+      if ( uoverd < 0.0f )
+        continue;
+      const float voverd = Dot( interm, edge0 ) * rcp;
+      if ( uoverd + voverd > 1.0f || voverd < 0.0f )
+        continue;
+      if ( rays.hit( ray, toverd,
+                     mesh->materials[ mesh->face_material[ myID ] ],
+                     this, this ) ) {
+        rays.getScratchpad< float >( SCRATCH_U )[ ray ] = uoverd;
+        rays.getScratchpad< float >( SCRATCH_V )[ ray ] = voverd;
+      }
+    }
+    return;
+  }
+
   const sse_t eps4 = set4( T_EPSILON );
 
   const Vector p0 = mesh->getVertex(myID, 0);

Modified: trunk/Model/Primitives/WaldTriangle.cc
==============================================================================
--- trunk/Model/Primitives/WaldTriangle.cc      (original)
+++ trunk/Model/Primitives/WaldTriangle.cc      Wed Feb  6 23:31:26 2008
@@ -205,6 +205,64 @@
     const int sse_begin = (ray_begin + 3) & (~3);
     const int sse_end   = (ray_end) & (~3);
 
+    if (sse_begin >= sse_end) { //no sse section exists.
+
+      const Real* const dir_k  = data->direction[axis];
+      const Real* const dir_ku = data->direction[ku];
+      const Real* const dir_kv = data->direction[kv];
+
+      float org_k = 0,
+        org_ku = 0, 
+        org_kv = 0,
+        f0 = 0;
+
+      if (HasCommonOrigin) {
+        org_k  = data->origin[axis][rays.begin()];
+        org_ku = data->origin[ku][rays.begin()];
+        org_kv = data->origin[kv][rays.begin()];
+        f0 = n_d - (org_k + n_u * org_ku + n_v * org_kv);
+      }
+
+      for (int i = rays.begin(); i < rays.end(); i++ ) {
+        const float nd0 = n_u * dir_ku[i] + n_v * dir_kv[i] + dir_k[i];
+        const float nd  = 1.f/nd0;
+
+        if (!HasCommonOrigin) {
+          org_k  = data->origin[axis][i];
+          org_ku = data->origin[ku][i];
+          org_kv = data->origin[kv][i];
+
+          f0 = n_d - (org_k + n_u * org_ku + n_v * org_kv);
+        }
+
+        const float f = f0 * nd;
+        // plane test
+        if ( f < T_EPSILON || f > data->minT[i] )
+          continue;
+
+        const float hu = org_ku + f*dir_ku[i];
+        const float hv = org_kv + f*dir_kv[i];
+        const float lambda = b_d + hu*b_nu + hv * b_nv;
+
+        // barycentric test
+        if ( lambda < 0.f )
+          continue;
+
+        const float mue = c_d + hu * c_nu + hv * c_nv;
+        if ( mue < 0.f || mue + lambda > 1.f )
+          continue;
+
+        const bool hit = rays.hit(i, f, 
mesh->materials[mesh->face_material[myID]], this, this);
+        if (hit) {
+          float *u = &rays.getScratchpad<float>(SCRATCH_U)[i];
+          float *v = &rays.getScratchpad<float>(SCRATCH_V)[i];
+          *u = lambda;
+          *v = mue;
+        }
+      }
+      return;
+    }
+
     const sse_t sse_n_u  = set4(n_u);
     const sse_t sse_n_v  = set4(n_v);
     const sse_t sse_n_d  = set4(n_d);




  • [Manta] r2039 - in trunk: Engine/Shadows Interface Model/Groups Model/Primitives, Thiago Ize, 02/07/2008

Archive powered by MHonArc 2.6.16.

Top of page