Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r1050 - in trunk: Interface Model/Materials


Chronological Thread 
  • From: sparker@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r1050 - in trunk: Interface Model/Materials
  • Date: Mon, 8 May 2006 18:01:24 -0600 (MDT)

Author: sparker
Date: Mon May  8 18:01:19 2006
New Revision: 1050

Modified:
   trunk/Interface/Parameters.h
   trunk/Model/Materials/Phong.cc
   trunk/Model/Materials/Phong.h
Log:
Uglified Phong with SSE


Modified: trunk/Interface/Parameters.h
==============================================================================
--- trunk/Interface/Parameters.h        (original)
+++ trunk/Interface/Parameters.h        Mon May  8 18:01:19 2006
@@ -32,6 +32,7 @@
 #define MAXCACHELINESIZE 128
 #define T_EPSILON ((Real)1.e-3)
 #define DENOM_EPSILON ((Real)1.e-6)
+#define COLOR_EPSILON ((Real)1.e-4)
 #define MAXT ((Real)1.e19)
 
 #endif

Modified: trunk/Model/Materials/Phong.cc
==============================================================================
--- trunk/Model/Materials/Phong.cc      (original)
+++ trunk/Model/Materials/Phong.cc      Mon May  8 18:01:19 2006
@@ -27,6 +27,10 @@
   DEALINGS IN THE SOFTWARE.
 */
 
+// TODO
+// SSE reflection code
+// SSE run length in computeNormal
+
 #include <Model/Materials/Phong.h>
 #include <Core/Math/ipow.h>
 #include <Interface/AmbientLight.h>
@@ -53,6 +57,7 @@
   speculartex = new Constant<Color>(specular);
   refltex = new Constant<ColorComponent>(refl);
   do_refl = (refl != 0);
+  highlight_threshold = pow(COLOR_EPSILON, 1./(2*specpow));
 }
 
 Phong::Phong(const Texture<Color>* diffusetex,
@@ -125,6 +130,133 @@
     // We need normalized directions for proper dot product computation.
     shadowRays.normalizeDirections();
 
+#ifdef MANTA_SSE
+    int b = (rays.rayBegin + 3) & (~3);
+    int e = rays.rayEnd & (~3);
+    if(b == e){
+      for(int i = rays.begin(); i < rays.end(); i++){
+        if(!shadowRays.wasHit(i)){
+          // Not in shadow, so compute the direct and specular contributions.
+          Vector normal = rays.getNormal(i);
+          Vector shadowdir = shadowRays.getDirection(i);
+          ColorComponent cos_theta = Dot(shadowdir, normal);
+          Color light = shadowRays.getColor(i);
+          for(int k = 0; k < Color::NumComponents;k++)
+            ambientAndDiffuseLight[k][i] += light[k]*cos_theta;
+          Vector dir = rays.getDirection(i);
+          Vector H = shadowdir-dir;
+          ColorComponent cos_alpha = Dot(H, normal);
+          if(cos_alpha > highlight_threshold){
+            Color::ComponentType length = H.length2();
+            Color::ComponentType scale = ipow(cos_alpha*cos_alpha/length, 
specpow);
+            for(int k=0;k<Color::NumComponents;k++)
+              specularLight[k][i] += light[k] * scale;
+          }
+        }
+      }
+    } else {
+      int i = rays.rayBegin;
+      for(;i<b;i++){
+        if(!shadowRays.wasHit(i)){
+          // Not in shadow, so compute the direct and specular contributions.
+          Vector normal = rays.getNormal(i);
+          Vector shadowdir = shadowRays.getDirection(i);
+          ColorComponent cos_theta = Dot(shadowdir, normal);
+          Color light = shadowRays.getColor(i);
+          for(int k = 0; k < Color::NumComponents;k++)
+            ambientAndDiffuseLight[k][i] += light[k]*cos_theta;
+          Vector dir = rays.getDirection(i);
+          Vector H = shadowdir-dir;
+          ColorComponent cos_alpha = Dot(H, normal);
+          if(cos_alpha > highlight_threshold){
+            Color::ComponentType length = H.length2();
+            Color::ComponentType scale = ipow(cos_alpha*cos_alpha/length, 
specpow);
+            for(int k=0;k<Color::NumComponents;k++)
+              specularLight[k][i] += light[k] * scale;
+          }
+        }
+      }
+      RayPacketData* data = rays.data;
+      RayPacketData* shadowData = shadowRays.data;
+      for(;i<e;i+=4){
+        __m128 mask = 
_mm_cmpeq_ps(_mm_load_ps((float*)&shadowData->hitMatl[i]), _mm_setzero_ps());
+        if(_mm_movemask_ps(mask) == 0)
+          continue;
+        // Not in shadow, so compute the direct and specular contributions.
+        __m128 normalx = _mm_load_ps(&data->normal[0][i]);
+        __m128 normaly = _mm_load_ps(&data->normal[1][i]);
+        __m128 normalz = _mm_load_ps(&data->normal[2][i]);
+        __m128 sdx = _mm_load_ps(&shadowData->direction[0][i]);
+        __m128 sdy = _mm_load_ps(&shadowData->direction[1][i]);
+        __m128 sdz = _mm_load_ps(&shadowData->direction[2][i]);
+        __m128 cos_theta = _mm_add_ps(_mm_add_ps(_mm_mul_ps(sdx, normalx), 
_mm_mul_ps(sdy, normaly)), _mm_mul_ps(sdz, normalz));
+
+        __m128 lightr = _mm_load_ps(&shadowData->color[0][i]);
+        __m128 lightg = _mm_load_ps(&shadowData->color[1][i]);
+        __m128 lightb = _mm_load_ps(&shadowData->color[2][i]);
+        if(_mm_movemask_ps(mask) == 0xf){
+          _mm_store_ps(&ambientAndDiffuseLight[0][i], 
_mm_add_ps(_mm_load_ps(&ambientAndDiffuseLight[0][i]), _mm_mul_ps(lightr, 
cos_theta)));
+          _mm_store_ps(&ambientAndDiffuseLight[1][i], 
_mm_add_ps(_mm_load_ps(&ambientAndDiffuseLight[1][i]), _mm_mul_ps(lightg, 
cos_theta)));
+          _mm_store_ps(&ambientAndDiffuseLight[2][i], 
_mm_add_ps(_mm_load_ps(&ambientAndDiffuseLight[2][i]), _mm_mul_ps(lightb, 
cos_theta)));
+        } else {
+          
_mm_maskmoveu_si128((__m128i)_mm_add_ps(_mm_load_ps(&ambientAndDiffuseLight[0][i]),
 _mm_mul_ps(lightr, cos_theta)), (__m128i)mask, 
(char*)&ambientAndDiffuseLight[0][i]);
+          
_mm_maskmoveu_si128((__m128i)_mm_add_ps(_mm_load_ps(&ambientAndDiffuseLight[1][i]),
 _mm_mul_ps(lightg, cos_theta)), (__m128i)mask, 
(char*)&ambientAndDiffuseLight[1][i]);
+          
_mm_maskmoveu_si128((__m128i)_mm_add_ps(_mm_load_ps(&ambientAndDiffuseLight[2][i]),
 _mm_mul_ps(lightb, cos_theta)), (__m128i)mask, 
(char*)&ambientAndDiffuseLight[2][i]);
+        }
+        
+        __m128 Hx = _mm_sub_ps(sdx, _mm_load_ps(&data->direction[0][i]));
+        __m128 Hy = _mm_sub_ps(sdy, _mm_load_ps(&data->direction[1][i]));
+        __m128 Hz = _mm_sub_ps(sdz, _mm_load_ps(&data->direction[2][i]));
+
+        __m128 cos_alpha = _mm_add_ps(_mm_add_ps(_mm_mul_ps(Hx, normalx), 
_mm_mul_ps(Hy, normaly)), _mm_mul_ps(Hz, normalz));
+        mask = _mm_and_ps(mask, _mm_cmpge_ps(cos_alpha, 
_mm_set1_ps(highlight_threshold)));
+        if(_mm_movemask_ps(mask) == 0)
+          continue;
+
+        __m128 length = _mm_add_ps(_mm_add_ps(_mm_mul_ps(Hx, Hx), 
_mm_mul_ps(Hy, Hy)), _mm_mul_ps(Hz, Hz));
+        __m128 scale = _mm_set1_ps(1.0f);
+        __m128 x = _mm_div_ps(_mm_mul_ps(cos_alpha, cos_alpha), length);
+        int p = specpow;
+        while(p){
+          if(p&1){
+            scale = _mm_mul_ps(scale, x);
+          }
+          x = _mm_mul_ps(x, x);
+          p>>=1;
+        }
+
+        if(_mm_movemask_ps(mask) == 0xf){
+          _mm_store_ps(&specularLight[0][i], 
_mm_add_ps(_mm_load_ps(&specularLight[0][i]), _mm_mul_ps(lightr, scale)));
+          _mm_store_ps(&specularLight[1][i], 
_mm_add_ps(_mm_load_ps(&specularLight[1][i]), _mm_mul_ps(lightg, scale)));
+          _mm_store_ps(&specularLight[2][i], 
_mm_add_ps(_mm_load_ps(&specularLight[2][i]), _mm_mul_ps(lightb, scale)));
+        } else {
+          
_mm_maskmoveu_si128((__m128i)_mm_add_ps(_mm_load_ps(&specularLight[0][i]), 
_mm_mul_ps(lightr, scale)), (__m128i)mask, (char*)&specularLight[0][i]);
+          
_mm_maskmoveu_si128((__m128i)_mm_add_ps(_mm_load_ps(&specularLight[1][i]), 
_mm_mul_ps(lightg, scale)), (__m128i)mask, (char*)&specularLight[1][i]);
+          
_mm_maskmoveu_si128((__m128i)_mm_add_ps(_mm_load_ps(&specularLight[2][i]), 
_mm_mul_ps(lightb, scale)), (__m128i)mask, (char*)&specularLight[2][i]);
+        }
+      }
+      for(;i<rays.rayEnd;i++){
+        if(!shadowRays.wasHit(i)){
+          // Not in shadow, so compute the direct and specular contributions.
+          Vector normal = rays.getNormal(i);
+          Vector shadowdir = shadowRays.getDirection(i);
+          ColorComponent cos_theta = Dot(shadowdir, normal);
+          Color light = shadowRays.getColor(i);
+          for(int k = 0; k < Color::NumComponents;k++)
+            ambientAndDiffuseLight[k][i] += light[k]*cos_theta;
+          Vector dir = rays.getDirection(i);
+          Vector H = shadowdir-dir;
+          ColorComponent cos_alpha = Dot(H, normal);
+          if(cos_alpha > highlight_threshold){
+            Color::ComponentType length = H.length2();
+            Color::ComponentType scale = ipow(cos_alpha*cos_alpha/length, 
specpow);
+            for(int k=0;k<Color::NumComponents;k++)
+              specularLight[k][i] += light[k] * scale;
+          }
+        }
+      }
+    }
+#else
     for(int i=shadowRays.begin(); i < shadowRays.end(); i++){
       if(!shadowRays.wasHit(i)){
         // Not in shadow, so compute the direct and specular contributions.
@@ -137,7 +269,7 @@
         Vector dir = rays.getDirection(i);
         Vector H = shadowdir-dir;
         ColorComponent cos_alpha = Dot(H, normal);
-        if(cos_alpha > 0){
+        if(cos_alpha > phong_threshold){
           Color::ComponentType length = H.length2();
           Color::ComponentType scale = ipow(cos_alpha*cos_alpha/length, 
specpow);
           for(int k=0;k<Color::NumComponents;k++)
@@ -145,6 +277,7 @@
         }
       }
     }
+#endif
     firstTime = false;
   } while(!done);
 

Modified: trunk/Model/Materials/Phong.h
==============================================================================
--- trunk/Model/Materials/Phong.h       (original)
+++ trunk/Model/Materials/Phong.h       Mon May  8 18:01:19 2006
@@ -27,6 +27,7 @@
     const Texture<Color>* diffusetex;
     const Texture<Color>* speculartex;
     const Texture<ColorComponent>* refltex;
+    Real highlight_threshold;
     int specpow;
     bool do_refl;
   };




  • [MANTA] r1050 - in trunk: Interface Model/Materials, sparker, 05/08/2006

Archive powered by MHonArc 2.6.16.

Top of page