Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r807 - in branches/vertical: Engine/Shadows Interface Model/AmbientLights Model/Lights Model/Materials


Chronological Thread 
  • From: sparker@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r807 - in branches/vertical: Engine/Shadows Interface Model/AmbientLights Model/Lights Model/Materials
  • Date: Wed, 28 Dec 2005 13:33:48 -0700 (MST)

Author: sparker
Date: Wed Dec 28 13:33:46 2005
New Revision: 807

Modified:
   branches/vertical/Engine/Shadows/BeamShadows.cc
   branches/vertical/Engine/Shadows/BeamShadows.h
   branches/vertical/Engine/Shadows/HardShadows.cc
   branches/vertical/Engine/Shadows/HardShadows.h
   branches/vertical/Engine/Shadows/NoShadows.cc
   branches/vertical/Engine/Shadows/NoShadows.h
   branches/vertical/Interface/AmbientLight.h
   branches/vertical/Interface/Light.h
   branches/vertical/Interface/RayPacket.h
   branches/vertical/Interface/ShadowAlgorithm.h
   branches/vertical/Model/AmbientLights/ConstantAmbient.cc
   branches/vertical/Model/AmbientLights/ConstantAmbient.h
   branches/vertical/Model/Lights/PointLight.cc
   branches/vertical/Model/Lights/PointLight.h
   branches/vertical/Model/Materials/Phong.cc
Log:
First pass at new light/shadowalgorithm interface.  About the same speed as 
before...


Modified: branches/vertical/Engine/Shadows/BeamShadows.cc
==============================================================================
--- branches/vertical/Engine/Shadows/BeamShadows.cc     (original)
+++ branches/vertical/Engine/Shadows/BeamShadows.cc     Wed Dec 28 13:33:46 
2005
@@ -57,9 +57,13 @@
 {
 }
 
-int BeamShadows::computeShadows(const RenderContext& context,
-                              const LightSet* lights, RayPacket& rays,
-                              int start, RayPacket& shadowRays)
+bool BeamShadows::computeShadows(const RenderContext& context,
+                                 const LightSet* lights, 
+                                 RayPacket& rays,              // Input rays.
+                                 int map[],                    // map from 
shadow rays to input rays
+                                 RayPacket& shadowRays,        // Output 
shadow rays, already intersected.
+                                 bool firstTime,
+                                 StateBuffer& stateBuffer)
 {
 #if 0
   int nlights = lights->numLights();

Modified: branches/vertical/Engine/Shadows/BeamShadows.h
==============================================================================
--- branches/vertical/Engine/Shadows/BeamShadows.h      (original)
+++ branches/vertical/Engine/Shadows/BeamShadows.h      Wed Dec 28 13:33:46 
2005
@@ -15,8 +15,9 @@
     BeamShadows(const vector<string>& args);
     virtual ~BeamShadows();
 
-    virtual int computeShadows(const RenderContext& context, const LightSet* 
lights,
-                              RayPacket&, int start, RayPacket&);
+    virtual bool computeShadows(const RenderContext& context, const 
LightSet* lights,
+                                RayPacket& source, int map[], RayPacket& 
shadowRays,
+                                bool firstTime, StateBuffer& stateBuffer);
 
     static ShadowAlgorithm* create(const vector<string>& args);
 

Modified: branches/vertical/Engine/Shadows/HardShadows.cc
==============================================================================
--- branches/vertical/Engine/Shadows/HardShadows.cc     (original)
+++ branches/vertical/Engine/Shadows/HardShadows.cc     Wed Dec 28 13:33:46 
2005
@@ -22,109 +22,68 @@
 {
 }
 
-int HardShadows::computeShadows(const RenderContext& context,
-                                const LightSet* lights, 
-                                RayPacket& rays,              // Input rays.
-                                int start,                    // Offset to 
start from in input rays?
-                                RayPacket& shadowRays)       // Output 
shadow rays, already intersected.
+bool HardShadows::computeShadows(const RenderContext& context,
+                                 const LightSet* lights, 
+                                 RayPacket& rays,              // Input rays.
+                                 int map[],                    // map from 
shadow rays to input rays
+                                 RayPacket& shadowRays,        // Output 
shadow rays, already intersected.
+                                 bool firstTime,
+                                 StateBuffer& stateBuffer)
 {
   int nlights = lights->numLights();
   
   // Compute the hit positions.
   rays.computeHitPositions();
   rays.computeNormals( context );
-       
-#if 0
-       // Construct a shadow ray packet.
-       // NOTE: this code won't send more then RayPacket::MaxSize shadow 
rays.
-       // Although the old code didn't either.
-       
-       Real   distance [RayPacket::MaxSize];
-       Color  color    [RayPacket::MaxSize];
-       Vector direction[RayPacket::MaxSize];
-
-       int shadow_i = 0; // Iterator over computed shadow rays.
-       int i = start;    // Iterator over initial rays used to compute 
shadow rays.
-       
-       // NEED TO MAKE SURE ORDER MATCHES MATERIAL SHADER!!
-       // WANT ALL RAYS TOWARDS ONE LIGHT TO BE COMMON PACKET.
-       // 
-       
-       // Iterate over the lights and compute directions, colors, distances.
-       for (int light=0; 
-            (light<lights->numLights()) && 
-                        (shadow_i<RayPacket::MaxSize); 
-                        ++light) {
-               
-               // Compute the info for this light.
-               lights->get(light)->getLight( distance, color, direction, 
rays, context );
-               
-               // Compute the shadow rays and append them to the shadow 
packet.
-               
-               // Set the shadow ray.
-               for (int i=0; ((shadow_i+i)<RayPacket::MaxSize) && 
(i<rays.getSize();++i) {
-                       shadowRays.get(shadow_i+i).ray.set( 
rays[i].hitPosition, direction[i] );
-               }
-               
-               // Copy the light contribution.
-               for (int i=0; ((shadow_i+i)<RayPacket::MaxSize) && 
(i<rays.getSize();++i) {             
-                       shadowRays.get(shadow_i+i).light = 
lights[light].color;
-               }       
-               
-               // Copy the distance.
-               for (int i=0; ((shadow_i+i)<RayPacket::MaxSize) && 
(i<rays.getSize();++i) {
-                       shadowRays.get(shadow_i+i).hitInfo.reset( distance[i] 
);
-               }
-               
-               // Move to the next part of the shadow ray packet.
-               shadow_i += rays.getSize();
-       }
-#endif
 
   int sidx = 0;
-  int end = start;
-  while(end < rays.end() && sidx+nlights <= RayPacket::MaxSize){
-
-    // Specify the beginning index for this ray in the shadow packet.
-    rays.setShadowBegin(end, sidx);
+  int starti, j;
+  if(firstTime){
+    starti = rays.begin();
+    j = 0;
+  } else {
+    starti = stateBuffer.i1;
+    j = stateBuffer.i2;
+  }
+  bool done = true;
+  for(; j < nlights; j++){
+    // Compute the contribution for this light.
+    Color lightColors[RayPacket::MaxSize];
+    Vector lightDirections[RayPacket::MaxSize];
+    lights->getLight(j)->computeLight( lightColors, lightDirections, 
context, rays);
 
-    // Iterate over the lights and create shadow rays.
-    for(int l=0;l<nlights;l++){
-               
-      Vector dir;
-      Color  color;
-               
-      // Compute the contribution for this light.
-      lights->getLight(l)->computeLight( color, dir, context, rays, end);
-      
+    for(int i = starti; i < rays.end(); i++){
       // Check to see if the light is on the front face.
-      if(Dot(dir, rays.getNormal(end)) > 0) {
-                       
+      Vector dir = lightDirections[i];
+      if(Dot(dir, rays.getNormal(i)) > 0) {
+
         // If so normalize and compute length.
         Real length = dir.normalize();
        
         // Populate the shadow ray.
-        shadowRays.setRay(sidx, rays.getHitPosition(end), dir );
-        shadowRays.setLight(sidx, color);
+        shadowRays.setRay(sidx, rays.getHitPosition(i), dir );
+        shadowRays.setResult(sidx, lightColors[i]);
         shadowRays.resetHit( sidx, length );
         sidx++;
       }
+
+      if(++sidx >= RayPacket::MaxSize && (j != nlights || i != rays.end())){
+        stateBuffer.i1 = i;
+        stateBuffer.i2 = j;
+        done = false;
+        j = nlights; // To break out of outer loop after we compute the 
light source contributions
+      }
     }
-    rays.setShadowEnd(end, sidx);
-    end++;
+    
+    starti = 0;
   }
-       
+      
   // Send the shadow rays.
   shadowRays.setFlag( 
RayPacket::NormalizedDirections|RayPacket::HaveHitRecords );
   shadowRays.resize ( sidx );
        
-  // Check to see if all of the shadow rays start from the same input ray.
-  if(end == start+1)
-    shadowRays.setFlag( RayPacket::ConstantOrigin );
-  
   context.scene->getObject()->intersect(context, shadowRays);
-       
-  return end;
+  return done;
 }
 
 string HardShadows::getName() const {

Modified: branches/vertical/Engine/Shadows/HardShadows.h
==============================================================================
--- branches/vertical/Engine/Shadows/HardShadows.h      (original)
+++ branches/vertical/Engine/Shadows/HardShadows.h      Wed Dec 28 13:33:46 
2005
@@ -15,8 +15,9 @@
     HardShadows(const vector<string>& args);
     virtual ~HardShadows();
 
-    virtual int computeShadows(const RenderContext& context, const LightSet* 
lights,
-                              RayPacket&, int start, RayPacket&);
+    virtual bool computeShadows(const RenderContext& context, const 
LightSet* lights,
+                                RayPacket& source, int map[], RayPacket& 
shadowRays,
+                                bool firstTime, StateBuffer& stateBuffer);
 
     static ShadowAlgorithm* create(const vector<string>& args);
 

Modified: branches/vertical/Engine/Shadows/NoShadows.cc
==============================================================================
--- branches/vertical/Engine/Shadows/NoShadows.cc       (original)
+++ branches/vertical/Engine/Shadows/NoShadows.cc       Wed Dec 28 13:33:46 
2005
@@ -19,40 +19,54 @@
 {
 }
 
-int NoShadows::computeShadows(const RenderContext& context,
-                              const LightSet* lights, RayPacket& rays,
-                              int start, RayPacket& shadowRays)
+bool NoShadows::computeShadows(const RenderContext& context, const LightSet* 
lights,
+                               RayPacket& sourceRays, int map[], RayPacket& 
shadowRays,
+                               bool firstTime, StateBuffer& stateBuffer)
 {
   int nlights = lights->numLights();
-  rays.computeHitPositions();
+  
+  // Compute the hit normals
+  rays.computeNormals( context );
 
   int sidx = 0;
-  while(start < rays.end() && sidx+nlights < RayPacket::MaxSize){
-    rays.setShadowBegin(start, sidx);
-    for(int l = 0;l<nlights;l++){
-      Color color;
-      Vector dir;
-               
-      // Compute the direction & color of this light.
-      lights->getLight(l)->computeLight(color,dir,context,rays, start);
-               
-      if(Dot(dir, rays.getNormal(start))  > 0){
-        // Be sure to normalize the normals
-        shadowRays.setDirection(sidx, dir.normal());
-        shadowRays.setLight(sidx, color);
+  int starti, j;
+  if(firstTime){
+    starti = rays.begin();
+    j = 0;
+  } else {
+    starti = stateBuffer.i1;
+    j = stateBuffer.i2;
+  }
+  bool done = true;
+  for(; j < nlights; j++){
+    // Compute the contribution for this light.
+    Color lightColors[RayPacket::MaxSize];
+    Vector lightDirections[RayPacket::MaxSize];
+    lights->getLight(j)->computeLight( lightColors, lightDirections, 
context, rays);
+
+    for(int i = starti; i < rays.end(); i++){
+      // Check to see if the light is on the front face.
+      Vector dir = lightDirections[i];
+      if(Dot(dir, rays.getNormal(i)) > 0) {
+        // Populate the shadow ray.
+        shadowRays.setDirection(sidx, dir );
+        shadowRays.setResult(sidx, lightColors[i]);
         sidx++;
       }
+
+      if(++sidx >= RayPacket::MaxSize && (j != nlights || i != rays.end())){
+        stateBuffer.i1 = i;
+        stateBuffer.i2 = j;
+        done = false;
+        j = nlights; // To break out of outer loop after we compute the 
light source contributions
+      }
     }
-    rays.setShadowEnd(start, sidx);
-    start++;
+    
+    starti = 0;
   }
-
-  // We already normalized the rays, so indicate that so we don't do
-  // redundant work.
-  shadowRays.setFlag( RayPacket::NormalizedDirections );
-  shadowRays.resize(sidx);
-  shadowRays.resetHits();
-  return start;
+      
+  shadowRays.resize ( sidx );  
+  return done;
 }
 
 string NoShadows::getName() const {

Modified: branches/vertical/Engine/Shadows/NoShadows.h
==============================================================================
--- branches/vertical/Engine/Shadows/NoShadows.h        (original)
+++ branches/vertical/Engine/Shadows/NoShadows.h        Wed Dec 28 13:33:46 
2005
@@ -15,8 +15,9 @@
     NoShadows(const vector<string>& args);
     virtual ~NoShadows();
 
-    virtual int computeShadows(const RenderContext& context, const LightSet* 
lights,
-                              RayPacket&, int start, RayPacket&);
+    virtual bool computeShadows(const RenderContext& context, const 
LightSet* lights,
+                                RayPacket& source, int map[], RayPacket& 
shadowRays,
+                                bool firstTime, StateBuffer& stateBuffer);
 
     static ShadowAlgorithm* create(const vector<string>& args);
 

Modified: branches/vertical/Interface/AmbientLight.h
==============================================================================
--- branches/vertical/Interface/AmbientLight.h  (original)
+++ branches/vertical/Interface/AmbientLight.h  Wed Dec 28 13:33:46 2005
@@ -6,6 +6,7 @@
 #include <sgi_stl_warnings_off.h>
 #include <string>
 #include <sgi_stl_warnings_on.h>
+#include <Interface/RayPacket.h>
 
 namespace Manta {
   class PreprocessContext;
@@ -17,7 +18,7 @@
     virtual ~AmbientLight();
 
     virtual void preprocess(const PreprocessContext& context) = 0;
-    virtual void computeAmbient(const RenderContext& context, RayPacket& 
rays) const = 0;
+    virtual void computeAmbient(const RenderContext& context, RayPacket& 
rays, ColorArray ambient) const = 0;
 
     // This function will return a newly allocated pointer of a string
     // representation of the object.  You should delete it yourself.

Modified: branches/vertical/Interface/Light.h
==============================================================================
--- branches/vertical/Interface/Light.h (original)
+++ branches/vertical/Interface/Light.h Wed Dec 28 13:33:46 2005
@@ -20,24 +20,15 @@
     // virtual const Point& getCenter() const = 0;
     // virtual const Color& getColor() const = 0;
 
-#if 0
     // This method is called on the light by the shadow algorithm. The color 
and direction 
     // produced by the light may change for each ray in the packet, and may 
change based 
     // on the render context.
-    virtual void computeLight( Real   lightDistance[RayPacket::MaxSize], 
-                               Color  resultColor[RayPacket::MaxSize], 
+    virtual void computeLight( Color  resultColor[RayPacket::MaxSize], 
                                Vector lightDirection[RayPacket::MaxSize], 
-                               RenderContext &context, RayPacket &rays, int 
which ) = 0;
-#endif
+                               const RenderContext &context, RayPacket 
&rays) const = 0;
 
-    // This method is called on the light by the shadow algorithm to compute
-    // the direction and contribution for one ray packet element.
-    // The direction is not normalized and the distance to the light from 
-    // the intersection must be computed.
-    virtual void computeLight( Color &resultColor, Vector &lightDirection,
-                               const RenderContext &context, RayPacket &e, 
int which ) const = 0;
   private:
-               // Lights may not be copied.
+    // Lights may not be copied.
     Light( const Light & );
     Light& operator = ( const Light & );
   };

Modified: branches/vertical/Interface/RayPacket.h
==============================================================================
--- branches/vertical/Interface/RayPacket.h     (original)
+++ branches/vertical/Interface/RayPacket.h     Wed Dec 28 13:33:46 2005
@@ -11,6 +11,7 @@
 #include <algorithm>
 
 namespace Manta {
+  class RenderContext;
   class RayPacketData {
   public:
     enum {
@@ -48,35 +49,12 @@
 
     // Char-based arrays
     char scratchpad_data[Size][MaxScratchpadSize];
-
-    // Temporarily here but will go when I redo the lighting...
-    Color::ComponentType ambientLight[Color::NumComponents][Size];
-    Color::ComponentType light[Color::NumComponents][Size];
-    int shadowBegin[Size];
-    int shadowEnd[Size];
   };
 
-  typedef Color::ComponentType 
ColorArray[Color::NumComponents][RayPacketData::Size];
-
-#if 0
-    struct Element {
-      Vector  inverseDirection;
-      int     sign[3];      // Mask describing ray direction, 1==negative 
0==positive,zero
-      Color   light;
-
-      int shadowBegin, shadowEnd;
-      int whichEye;
-    };
-
-#endif
-
-
-  class RayPacketData;
-  class RenderContext;
   class RayPacket {
   public:
     enum {
-      MaxSize               = 32,
+      MaxSize               = RayPacketData::Size,
 
       // Flags.
       ConstantOrigin        = 0x0001,
@@ -180,47 +158,6 @@
       return result;
     }
 
-    void setAmbientLight(int which, const Color& ambientLight)
-    {
-      for(int i=0;i<Color::NumComponents;i++)
-        data->ambientLight[i][which] = ambientLight[i];
-    }
-    Color getAmbientLight(int which)
-    {
-      Color result;
-      for(int i=0;i<Color::NumComponents;i++)
-        result[i] = data->ambientLight[i][which];
-      return result;
-    }
-    void setLight(int which, const Color& light)
-    {
-      for(int i=0;i<Color::NumComponents;i++)
-        data->light[i][which] = light[i];
-    }
-    Color getLight(int which)
-    {
-      Color result;
-      for(int i=0;i<Color::NumComponents;i++)
-        result[i] = data->light[i][which];
-      return result;
-    }
-    int shadowBegin(int which)
-    {
-      return data->shadowBegin[which];
-    }
-    int shadowEnd(int which)
-    {
-      return data->shadowEnd[which];
-    }
-    void setShadowBegin(int which, int s)
-    {
-      data->shadowBegin[which] = s;
-    }
-    void setShadowEnd(int which, int s)
-    {
-      data->shadowEnd[which] = s;
-    }
-
     Real getImageCoordinates(int which, int dim)
     {
       return data->image[dim][which];
@@ -475,6 +412,8 @@
     int depth;
     int flags;
   };
+
+  typedef Color::ComponentType 
ColorArray[Color::NumComponents][RayPacket::MaxSize];
 
 } // end namespace Manta
 

Modified: branches/vertical/Interface/ShadowAlgorithm.h
==============================================================================
--- branches/vertical/Interface/ShadowAlgorithm.h       (original)
+++ branches/vertical/Interface/ShadowAlgorithm.h       Wed Dec 28 13:33:46 
2005
@@ -3,6 +3,7 @@
 #ifndef Manta_Interface_ShadowAlgorithm_h
 #define Manta_Interface_ShadowAlgorithm_h
 
+#include <Interface/RayPacket.h>
 #include <sgi_stl_warnings_off.h>
 #include <string>
 #include <sgi_stl_warnings_on.h>
@@ -12,14 +13,42 @@
   class RayPacket;
   class RenderContext;
 
+
   class ShadowAlgorithm {
   public:
     ShadowAlgorithm();
     virtual ~ShadowAlgorithm();
 
-    virtual int computeShadows(const RenderContext& context, const LightSet* 
lights,
-                              RayPacket&, int start, RayPacket&) = 0;
+    struct StateBuffer {
+      // Most shadowAlgorithms will only need to store an int or two in the
+      // state buffer, so we can get alignment guarantees and avoid cast
+      // nastiness by supplying them here.  If you use cast() below, these
+      // are part of the casted object.  Callers of the shadow algorithm
+      // should not assume anything about the data in this object!
+      int i1, i2;
+
+      template<class T> T& cast() {
+
+        // This pragma relates to the following expression being
+        // constant (which it is).  Since sizeof(T) is evaluated after
+        // the preprocessor, we can't get around not doing it here like
+        // this.
+
+#     if defined(__sgi) && !defined(__GNUC__)
+#       pragma set woff 1209
+        ASSERT(sizeof(T) <= sizeof(*this));
+#       pragma set woff 1209
+#     else
+        ASSERT(sizeof(T) <= sizeof(*this));
+#     endif
+        return *(T*)this;
+      }
+    };
 
+    virtual bool computeShadows(const RenderContext& context, const 
LightSet* lights,
+                                RayPacket& source, int map[], RayPacket& 
shadowRays,
+                                bool firstTime, StateBuffer& stateBuffer) = 
0;
+    
     virtual std::string getName() const = 0;
     virtual std::string getSpecs() const = 0;
 

Modified: branches/vertical/Model/AmbientLights/ConstantAmbient.cc
==============================================================================
--- branches/vertical/Model/AmbientLights/ConstantAmbient.cc    (original)
+++ branches/vertical/Model/AmbientLights/ConstantAmbient.cc    Wed Dec 28 
13:33:46 2005
@@ -24,10 +24,12 @@
 }
 
 void ConstantAmbient::computeAmbient(const RenderContext&,
-                                    RayPacket& rays) const
+                                    RayPacket& rays,
+                                     ColorArray ambient) const
 {
   for(int i=rays.begin();i<rays.end();i++)
-    rays.setAmbientLight(i, color);
+    for(int j=0;j<Color::NumComponents;j++)
+      ambient[j][i] = color[j];
 }
 
 string ConstantAmbient::toString() const {

Modified: branches/vertical/Model/AmbientLights/ConstantAmbient.h
==============================================================================
--- branches/vertical/Model/AmbientLights/ConstantAmbient.h     (original)
+++ branches/vertical/Model/AmbientLights/ConstantAmbient.h     Wed Dec 28 
13:33:46 2005
@@ -16,7 +16,7 @@
     virtual ~ConstantAmbient();
 
     virtual void preprocess(const PreprocessContext&);
-    virtual void computeAmbient(const RenderContext& context, RayPacket& 
rays) const;
+    virtual void computeAmbient(const RenderContext& context, RayPacket& 
rays, ColorArray ambient) const;
 
     virtual std::string toString() const;
   private:

Modified: branches/vertical/Model/Lights/PointLight.cc
==============================================================================
--- branches/vertical/Model/Lights/PointLight.cc        (original)
+++ branches/vertical/Model/Lights/PointLight.cc        Wed Dec 28 13:33:46 
2005
@@ -16,14 +16,12 @@
 {
 }
 
-void PointLight::computeLight( Color &resultColor, Vector &lightDirection,
-                               const RenderContext &/*context*/,
-                               RayPacket& rays, int which ) const
+void PointLight::computeLight( Color  resultColor[RayPacket::MaxSize], 
+                               Vector lightDirection[RayPacket::MaxSize], 
+                               const RenderContext &context, RayPacket 
&rays) const
 {
-  
-  // Specify the color.
-  resultColor = color;
-       
-  // Compute the light direction.
-  lightDirection = (position - rays.getHitPosition(which));
+  for(int i = rays.begin(); i < rays.end(); i++){
+    resultColor[i] = color;
+    lightDirection[i] = position - rays.getHitPosition(i);
+  }
 }

Modified: branches/vertical/Model/Lights/PointLight.h
==============================================================================
--- branches/vertical/Model/Lights/PointLight.h (original)
+++ branches/vertical/Model/Lights/PointLight.h Wed Dec 28 13:33:46 2005
@@ -14,10 +14,9 @@
 
     virtual void preprocess(const PreprocessContext&);
     
-    virtual void computeLight( Color &resultColor, Vector &lightDirection,
-                               const RenderContext &context, RayPacket & 
rays,
-                               int which ) const;
-               
+    virtual void computeLight( Color  resultColor[RayPacket::MaxSize], 
+                               Vector lightDirection[RayPacket::MaxSize], 
+                               const RenderContext &context, RayPacket 
&rays) const;
   private:
     Point position;
     Color color;

Modified: branches/vertical/Model/Materials/Phong.cc
==============================================================================
--- branches/vertical/Model/Materials/Phong.cc  (original)
+++ branches/vertical/Model/Materials/Phong.cc  Wed Dec 28 13:33:46 2005
@@ -64,49 +64,70 @@
   rays.computeNormals(context);
 
   // Compute ambient contributions for all rays
-  activeLights->getAmbientLight()->computeAmbient(context, rays);
+  ColorArray ambientAndDiffuseLight;
+  activeLights->getAmbientLight()->computeAmbient(context, rays, 
ambientAndDiffuseLight);
 
-  // We normalized directions for proper dot product computation.
+  // Initialize specular to zero
+  ColorArray specularLight;
+  for(int i = rays.begin(); i < rays.end(); i++)
+    for(int j=0;j<Color::NumComponents;j++)
+      specularLight[j][i] = 0;
+
+  // We need normalized directions for proper dot product computation.
   rays.normalizeDirections();
 
-  int start = rays.begin();
+  RayPacketData shadowData;
+  int map[RayPacket::MaxSize];
 
+  ShadowAlgorithm::StateBuffer stateBuffer;
+  bool firstTime = true;
+  bool done;
   do {
-    RayPacketData shadowData;
     RayPacket shadowRays(shadowData, 0, 0, rays.getDepth(), 0);
 
-    // Call the shadowalgorithm to generate shadow rays.  The shadowAlgorithm
-    // will potentially increment the light index.  If some lights do not
-    // get any shadows, it can increment by more than one at a time.
-    int end = context.shadowAlgorithm->computeShadows(context, activeLights,
-                                                      rays, start, 
shadowRays);
+    // Call the shadowalgorithm(sa) to generate shadow rays.  We may not be
+    // able to compute all of them, so we pass along a buffer for the sa
+    // object to store it's state.  The firstTime flag tells the sa to fill
+    // in the state rather than using anything in the state buffer.  Most
+    // sas will only need to store an int or two in the statebuffer.
+    done = context.shadowAlgorithm->computeShadows(context, activeLights,
+                                                   rays, map, shadowRays,
+                                                   firstTime, stateBuffer);
 
-    // We normalized directions for proper dot product computation.
+    // We need normalized directions for proper dot product computation.
     shadowRays.normalizeDirections();
-    for(int i=start;i<end;i++){
-      // Initialize with the ambient contribution.
-      Color totalDiffuse(rays.getAmbientLight(i));
-      Color totalSpecular = Color::black();
-      Vector normal = rays.getNormal(i);
-      Vector dir = rays.getDirection(i);
-      for(int j=rays.shadowBegin(i);j<rays.shadowEnd(i);j++){
-        if(!shadowRays.wasHit(j)){
-          // Not in shadow, so compute the direct and specular contributions.
-          Vector shadowdir = shadowRays.getDirection(j);
-          ColorComponent cos_theta = Dot(shadowdir, normal);
-          totalDiffuse += shadowRays.getLight(j)*cos_theta;
-          Vector H = shadowdir-dir;
-          ColorComponent cos_alpha = Dot(H, normal);
-          if(cos_alpha > 0){
-            ColorComponent length = H.length();
-            totalSpecular += shadowRays.getLight(j) * ipow(cos_alpha/length, 
specpow);
-          }
+
+    for(int j=shadowRays.begin(); j < shadowRays.end(); j++){
+      if(!shadowRays.wasHit(j)){
+        // Not in shadow, so compute the direct and specular contributions.
+        int to = map[j];
+        Vector normal = rays.getNormal(to);
+        Vector shadowdir = shadowRays.getDirection(j);
+        ColorComponent cos_theta = Dot(shadowdir, normal);
+        Color light = shadowRays.getResult(j);
+        for(int k = 0; k < Color::NumComponents;k++)
+          ambientAndDiffuseLight[k][to] += light[k]*cos_theta;
+        Vector dir = rays.getDirection(to);
+        Vector H = shadowdir-dir;
+        ColorComponent cos_alpha = Dot(H, normal);
+        if(cos_alpha > 0){
+          Color::ComponentType length = H.length();
+          Color::ComponentType scale = ipow(cos_alpha/length, specpow);
+          for(int k=0;k<Color::NumComponents;k++)
+            specularLight[k][to] += light[k] * scale;
         }
       }
-      rays.setResult(i, diffuse[i]*totalDiffuse+specular[i]*totalSpecular);
     }
-    start = end;
-  } while(start < rays.end());
+    firstTime = false;
+  } while(!done);
+
+  // Sum up diffuse/specular contributions
+  for(int i = rays.begin(); i < rays.end(); i++){
+    Color result;
+    for(int j=0;j<Color::NumComponents;j++)
+      result[j] = specularLight[j][i] * specular[j][i] + 
ambientAndDiffuseLight[j][i] * diffuse[j][i];
+    rays.setResult(i, result);
+  }
 
   // Compute reflections
   if(do_refl && rays.getDepth() < 
context.scene->getRenderParameters().maxDepth){




  • [MANTA] r807 - in branches/vertical: Engine/Shadows Interface Model/AmbientLights Model/Lights Model/Materials, sparker, 12/28/2005

Archive powered by MHonArc 2.6.16.

Top of page