Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r375 - in swig: Core/Geometry Engine/PixelSamplers


Chronological Thread 
  • From: bigler@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r375 - in swig: Core/Geometry Engine/PixelSamplers
  • Date: Fri, 10 Jun 2005 17:11:48 -0600 (MDT)

Author: bigler
Date: Fri Jun 10 17:11:47 2005
New Revision: 375

Modified:
   swig/Core/Geometry/PointVector.cc
   swig/Engine/PixelSamplers/JitterSampler.cc
   swig/Engine/PixelSamplers/JitterSampler.h
   swig/Engine/PixelSamplers/SingleSampler.cc
Log:

Core/Geometry/PointVector.cc

        Don't declare the function inline when the prototype in the
        header isn't.


Engine/PixelSamplers/JitterSampler.cc
Engine/PixelSamplers/JitterSampler.h

        Got rid of temporal aliasing with a performance hit.  Added a
        prototype replacement implementation of renderFragment that
        isn't quite debugged yet (it isn't used by default).  Try to
        be better about floating point types.

Engine/PixelSamplers/SingleSampler.cc

        Added some comments that help explain what is going on.


Modified: swig/Core/Geometry/PointVector.cc
==============================================================================
--- swig/Core/Geometry/PointVector.cc   (original)
+++ swig/Core/Geometry/PointVector.cc   Fri Jun 10 17:11:47 2005
@@ -1,17 +1,20 @@
 
 #include <Core/Geometry/PointVector.h>
+
+#include <sgi_stl_warnings_off.h>
 #include <iostream>
+#include <sgi_stl_warnings_on.h>
 
 namespace Manta {
   template<typename T, int Dim>
-  inline std::ostream &operator<< (std::ostream &os, const VectorT<T,Dim> 
&v) {
+  std::ostream &operator<< (std::ostream &os, const VectorT<T,Dim> &v) {
     for (int i=0;i<Dim;++i)
       os << v[i] << " ";
     return os;
   }
 
   template<typename T, int Dim>
-  inline std::ostream &operator<< (std::ostream &os, const PointT<T,Dim> &v) 
{
+  std::ostream &operator<< (std::ostream &os, const PointT<T,Dim> &v) {
     for (int i=0;i<Dim;++i)
       os << v[i] << " ";
     return os;

Modified: swig/Engine/PixelSamplers/JitterSampler.cc
==============================================================================
--- swig/Engine/PixelSamplers/JitterSampler.cc  (original)
+++ swig/Engine/PixelSamplers/JitterSampler.cc  Fri Jun 10 17:11:47 2005
@@ -13,6 +13,11 @@
 
 using namespace Manta;
 
+#include <sgi_stl_warnings_off.h>
+#include <iostream>
+#include <sgi_stl_warnings_on.h>
+using namespace std;
+
 PixelSampler* JitterSampler::create(const vector<string>& args)
 {
   
@@ -28,6 +33,9 @@
     if(arg == "-numberOfSamples"){
       if(!getIntArg(i, args, num_samples))
        throw IllegalArgument("JitterSampler -numberOfSamples", i, args);
+      if (num_samples < 1)
+        throw IllegalArgument("-numberOfSamples must be greater than 0",
+                              i, args);
     }
    
     else {
@@ -48,10 +56,6 @@
 {
   channelInfo.resize(numChannels);
   random = new MT_RNG[context.numProcs];
-  for(int i = 0; i < context.numProcs; i++)
-    {
-      random[i].seed_rng(static_cast<unsigned long>(i));
-    }
   context.renderer->setupBegin(context, numChannels);
 }
 
@@ -59,14 +63,13 @@
 {
   ChannelInfo& ci = channelInfo[context.channelIndex];
   bool stereo;
-  int xres, yres;
-  context.getResolution(stereo, xres, yres);
+  context.getResolution(stereo, ci.xres, ci.yres);
 
   // Set up the scale from -1 to 1
-  ci.xscale = 2./xres;
+  ci.xscale = (Real)2/ci.xres;
   ci.yscale = ci.xscale;
-  ci.xoffset = (-xres/2.+0.5)*ci.xscale; // Offset to pixel center
-  ci.yoffset = (-yres/2.+0.5)*ci.yscale;
+  ci.xoffset = (-ci.xres+1)*(Real)0.5*ci.xscale; // Offset to pixel center
+  ci.yoffset = (-ci.yres+1)*(Real)0.5*ci.yscale;
   
   context.renderer->setupDisplayChannel(context);
 }
@@ -78,6 +81,135 @@
 
 
 
+void JitterSampler::computeAverages(Fragment& fragment, RayPacket& rays,
+                                    Color* sample_color,
+                                    int* fragment_owning_sample) {
+  // At this point we have rays.getSize() number of samples
+  // that can belong to at most fragment.getSize() number of
+  // fragments.  We need to sum the colors from the samples
+  // for a single fragment then divide it by the total
+  // number of samples and add it to the fragment's total.
+  int slot_index = 0;
+  int num_samples_per_fragment = 1;
+  int current_fragment = fragment_owning_sample[slot_index];
+  Color fragment_color = sample_color[slot_index];
+  cerr << "=============================================================\n";
+  cerr << "rays.getSize() = "<<rays.getSize()<<"\n";
+  //  cerr << "slot_index = "<<slot_index<<", num_samples_per_fragment = 
"<<num_samples_per_fragment<<", "<<current_fragment<<"\n";
+  for(slot_index = 1; slot_index < rays.getSize(); slot_index++){
+    cerr << "slot_index = "<<slot_index<<", nspf = 
"<<num_samples_per_fragment<<", cf = "<<current_fragment<<", 
fragment_owning_sample_own_samp["<<slot_index<<"] = 
"<<fragment_owning_sample[slot_index]<<"\n";
+    bool compute_average = false;
+    if (current_fragment == fragment_owning_sample[slot_index]) {
+      cerr << "current_fragment == fragment_owning_sample[slot_index]\n";
+      fragment_color += sample_color[slot_index];
+      num_samples_per_fragment++;
+      // Now the case where the last sample is has been
+      // reached, we must force it to be averaged.
+      if (slot_index == rays.getSize()-1) {
+        cerr << "slot_index == rays.getSize()-1\n";
+        compute_average = true;
+      }
+    } else {
+      // Now we have a break in the fragment, so time to
+      // compute the average.
+      compute_average = true;
+    }
+    if (compute_average) {
+      cerr << "computing average for fragment " << current_fragment <<"\n";
+      // Divide the color by the number of samples and
+      // increment it with the fragment.
+      fragment.get(current_fragment).color +=
+        fragment_color / num_samples;
+      // Now update for the next fragment run
+      fragment_color = sample_color[slot_index];
+      current_fragment = fragment_owning_sample[slot_index];
+      num_samples_per_fragment = 1;
+    }
+  } // end slot_index loop
+}
+
+#if 0
+
+void JitterSampler::renderFragment(const RenderContext& context,
+                                  Fragment& fragment)
+{
+  ChannelInfo& ci = channelInfo[context.channelIndex];
+  int thd_num = context.proc;
+    
+  int flags = RayPacket::HaveImageCoordinates;
+  if(fragment.getFlags() & Fragment::ConstantEye)
+    flags |= RayPacket::ConstantEye;
+
+  int next_slot = 0;
+  Color sample_color[RayPacket::MaxSize];
+  int fragment_owning_sample[RayPacket::MaxSize];
+
+  int consecutivex_flag = fragment.getFlags() & Fragment::ConsecutiveX;
+
+//   if (consecutivex_flag) {
+//     Fragment::Element& fe = fragment.get(0);
+//     random[thd_num].seed_rng(fe.x*ci.xres+fe.y);
+//   }
+
+  int depth = 0;
+  RayPacketData raydata;
+  RayPacket rays(raydata, RayPacket::MaxSize, depth, flags);
+
+  Real inx = (Real)1/nx;
+  Real iny = (Real)1/ny;
+  Real px, py;
+  
+  // We can compute at most RayPacket::MaxSize number of rays at time.
+  for(int frag_index = 0; frag_index < fragment.getSize(); frag_index++) {
+    // Initialize the color
+    fragment.get(frag_index).color = Color::black();
+
+    Fragment::Element& fe0 = fragment.get(frag_index);
+
+    if (!consecutivex_flag) {
+      random[thd_num].seed_rng(fe0.x*ci.xres+fe0.y);
+    }
+    
+    // For each fragment start filling up the RayPacket with samples.
+    // When you filled up the empty_slots compute the rays, do the
+    // average, and store the results in the fragment.
+    for(int xs = 0; xs < nx; xs++)
+      for(int ys = 0; ys  < ny; ys++)
+        {
+          Real x_sample = (xs + random[thd_num].genRealRand<Real>()) * inx;
+          Real y_sample = (ys + random[thd_num].genRealRand<Real>()) * iny;
+          px = ((fe0.x+(x_sample))*ci.xscale+ci.xoffset);
+          py =  (fe0.y+(y_sample))*ci.yscale+ci.yoffset;
+          rays.setPixel(next_slot, 0, px, py, &sample_color[next_slot]);
+          fragment_owning_sample[next_slot] = frag_index;
+          next_slot++;
+          
+          if (next_slot == RayPacket::MaxSize) {
+            rays.resize(next_slot);
+            (context.renderer->traceEyeRays(context, rays));
+
+            computeAverages(fragment, rays,
+                            sample_color, fragment_owning_sample);
+            
+            // Now reset the index, so that we can start filling up
+            // the RayPacket again.
+            next_slot = 0;
+            // Make sure we start with a fresh slate
+            rays.resetHit();
+            //            rays.resetFlag(flags);
+          }
+        } // end sample filling loops
+  } // end fragment loop
+
+  // Pick up any stragling samples
+  if (next_slot > 0) {
+    rays.resize(next_slot);
+    (context.renderer->traceEyeRays(context, rays));
+    
+    computeAverages(fragment, rays, sample_color, fragment_owning_sample);
+  }
+}  
+#else
 void JitterSampler::renderFragment(const RenderContext& context,
                                   Fragment& fragment)
 {
@@ -99,18 +231,21 @@
     Color result[RayPacket::MaxSize];
     if(fragment.getFlags() & Fragment::ConsecutiveX) {
       Fragment::Element& fe0 = fragment.get(f);
+      random[thd_num].seed_rng(fe0.x*ci.xres+fe0.y);
       int i = 0;
       int count = 0;
       Real px, py;
-
+      Real inx = (Real)1/nx;
+      Real iny = (Real)1/ny;
+      
       while(i < size){
         for(int xs = 0; xs < nx; xs++)
           for(int ys = 0; ys  < ny; ys++)
          {
-            Real x_sample = ((Real)xs + random[thd_num].genRealRand<Real>()) 
/ (Real)nx;
-            Real y_sample = ((Real)ys + random[thd_num].genRealRand<Real>()) 
/ (Real)ny;
+            Real x_sample = (xs + random[thd_num].genRealRand<Real>()) * inx;
+            Real y_sample = (ys + random[thd_num].genRealRand<Real>()) * iny;
            px = ((fe0.x+(x_sample))*ci.xscale+ci.xoffset)+count*ci.xscale;
-           py = (fe0.y+(y_sample))*ci.yscale+ci.yoffset;
+           py =  (fe0.y+(y_sample))*ci.yscale+ci.yoffset;
            rays.setPixel(i, 0, px, py, &result[i]);
            i++;
          } 
@@ -124,18 +259,20 @@
       int i = 0;
       int count = 0;
       Real px, py;
+      Real inx = (Real)1/nx;
+      Real iny = (Real)1/ny;
 
       while(i < size){
        Fragment::Element& fe0 = fragment.get(f+i);
+        random[thd_num].seed_rng(fe0.x*ci.xres+fe0.y);
         for(int xs = 0; xs < nx; xs++)
           for(int ys = 0; ys  < ny; ys++)
          {
-            Real x_sample = ((Real)xs + random[thd_num].genRealRand<Real>()) 
/ (Real)nx;
-            Real y_sample = ((Real)ys + random[thd_num].genRealRand<Real>()) 
/ (Real)ny;
+            Real x_sample = (xs + random[thd_num].genRealRand<Real>()) * inx;
+            Real y_sample = (ys + random[thd_num].genRealRand<Real>()) * iny;
            px = ((fe0.x+x_sample)*ci.xscale+ci.xoffset)+count*ci.xscale;
-           py = (fe0.y+y_sample)*ci.yscale+ci.yoffset;
+           py =  (fe0.y+y_sample)*ci.yscale+ci.yoffset;
            rays.setPixel(i, 1, px, py, &result[i]);
-           
            i++;
          } 
        
@@ -151,25 +288,21 @@
     
     int element_index = 0;
     
-    float inv_num_samples = 1.0f/num_samples;
-    for(int k = 0; k < size; k+=num_samples)
-      {
-       Color final_col = Color::black();
-       for(int l = 0; l < num_samples; l++)
-         {
-           final_col += result[k+l];
-         }
-       
-       Fragment::Element& fe = fragment.get(f+element_index);
-       fe.color = final_col * inv_num_samples;
-       element_index++;
-       
+    ColorComponent inv_num_samples = (ColorComponent)1/num_samples;
+    for(int k = 0; k < size; k+=num_samples) {
+      Color final_col = result[k];
+      for(int l = 1; l < num_samples; l++) {
+        final_col += result[k+l];
       }
+      
+      Fragment::Element& fe = fragment.get(f+element_index);
+      fe.color = final_col * inv_num_samples;
+      element_index++;
+    }
     
-  }
-  
-
+  } // end fragment iterator
 }
+#endif
 
 
 

Modified: swig/Engine/PixelSamplers/JitterSampler.h
==============================================================================
--- swig/Engine/PixelSamplers/JitterSampler.h   (original)
+++ swig/Engine/PixelSamplers/JitterSampler.h   Fri Jun 10 17:11:47 2005
@@ -14,6 +14,8 @@
 
 namespace Manta {
   using namespace std;
+  class RayPacket;
+  
   class JitterSampler : public PixelSampler {
   public:
     JitterSampler(const vector<string>& args);
@@ -28,15 +30,20 @@
   private:
     JitterSampler(const JitterSampler&);
     JitterSampler& operator=(const JitterSampler&);
+
+    void computeAverages(Fragment& fragment, RayPacket& rays,
+                         Color* sample_color, int* fragment_owning_sample);
+    
     int num_samples;
     // nx*ny == num_samples where nx~=ny (or as close as you can get it).
     int nx, ny;
     
     struct ChannelInfo {
-      double xscale;
-      double xoffset;
-      double yscale;
-      double yoffset;
+      Real xscale;
+      Real xoffset;
+      Real yscale;
+      Real yoffset;
+      int xres, yres;
     };
 
     MT_RNG *random;

Modified: swig/Engine/PixelSamplers/SingleSampler.cc
==============================================================================
--- swig/Engine/PixelSamplers/SingleSampler.cc  (original)
+++ swig/Engine/PixelSamplers/SingleSampler.cc  Fri Jun 10 17:11:47 2005
@@ -54,8 +54,13 @@
   if(fragment.getFlags() & Fragment::ConstantEye)
     flags |= RayPacket::ConstantEye;
   for(int f=0;f<fragment.getSize();f+=RayPacket::MaxSize){
+    // We want to fill our RayPacket with as many as
+    // RayPacket::MaxSize rays.
     int size = RayPacket::MaxSize;
     if(size >= fragment.getSize()-f)
+      // We don't have enough fragments left to fill a ray packet, so
+      // set the size of the RayPacket to the number of fragments we
+      // have left.
       size = fragment.getSize()-f;
     // Create a ray packet
     int depth = 0;




  • [MANTA] r375 - in swig: Core/Geometry Engine/PixelSamplers, bigler, 06/10/2005

Archive powered by MHonArc 2.6.16.

Top of page