Text archives Help
- 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.