Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r1076 - in trunk: Engine/Control Model/Materials Model/Primitives scenes


Chronological Thread 
  • From: cgribble@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r1076 - in trunk: Engine/Control Model/Materials Model/Primitives scenes
  • Date: Fri, 19 May 2006 14:15:53 -0600 (MDT)

Author: cgribble
Date: Fri May 19 14:15:52 2006
New Revision: 1076

Modified:
   trunk/Engine/Control/DynPLTWorker.cc
   trunk/Model/Materials/DynPLTMaterial.cc
   trunk/Model/Primitives/Sphere.cc
   trunk/scenes/dynplt.cc
Log:
Model/Materials/DynPLTMaterial.cc
  Fixed (some) of the interpolation errors; still getting a weird spot on the 
top
    of the particles, but not sure why

Engine/Control/DynPLTWorker.cc
  Clean-up and some debugging; shading works, direct lighting does not
  Haven't worked on indirect lighting yet

scenes/dynplt.cc
  Added cmdln parameter for changing number of samples
  Added several bookmarks for debugging

Model/Primitives/Sphere.cc
  Fixed texture mapping routines


Modified: trunk/Engine/Control/DynPLTWorker.cc
==============================================================================
--- trunk/Engine/Control/DynPLTWorker.cc        (original)
+++ trunk/Engine/Control/DynPLTWorker.cc        Fri May 19 14:15:52 2006
@@ -1,5 +1,6 @@
 #include <Interface/Background.h>
 #include <Interface/Context.h>
+#include <Interface/Packet.h>
 #include <Interface/Scene.h>
 #include <Engine/Control/DynPLTWorker.h>
 #include <Engine/Shadows/HardShadows.h>
@@ -37,7 +38,7 @@
   for (unsigned int i=0; i<context->ngroups; ++i) {
     sample_groups[i].resize(context->nsamples);
 
-    // Generate random (u, v) offsets into the texel
+    // Generate random (u, v) samples in the texel --> [-0.5, 0.5]
     unsigned int idx=0;
     unsigned int nsamples_root=context->nsamples_root;
     Real delta=1/static_cast<Real>(nsamples_root);
@@ -45,8 +46,9 @@
     for (unsigned int j=0; j<nsamples_root; ++j) {
       Real v=0;
       for (unsigned int k=0; k<nsamples_root; ++k) {
-        sample_groups[i][idx++]=Vector2D(u + delta*rng.gendrand(),
-                                         v + delta*rng.gendrand());
+        sample_groups[i][idx++]=Vector2D(u - 0.5 + delta*rng.gendrand(),
+                                         v - 0.5 + delta*rng.gendrand());
+
         v += delta;
       }
 
@@ -74,11 +76,8 @@
   delete [] hidx;
 }
 
-// #define DEBUG 1
-#if DEBUG
 #include <iostream>
 using std::cerr;
-#endif
 
 void DynPLTWorker::run(void)
 {
@@ -108,15 +107,20 @@
     if (!dynplt || dynplt->valid)
       continue;
 
+    // Intialize the texture (use memset?)
+    unsigned int xres=dynplt->getXRes();
+    unsigned int yres=dynplt->getYRes();
+    Real inv_width=1/static_cast<Real>(xres - 1);
+    Real inv_height=1/static_cast<Real>(yres - 1);
+
+    for (unsigned int v=0; v<yres; ++v)
+      for (unsigned int u=0; u<xres; ++u)
+        dynplt->texture[u][v]=0;
+
     // Generate particle's texture
     Vector center=particle->getCenter();
     Real radius=particle->getRadius();
 
-    unsigned int xres=dynplt->getXRes();
-    unsigned int yres=dynplt->getYRes();
-    Real inv_xres=1/static_cast<Real>(xres);
-    Real inv_yres=1/static_cast<Real>(yres);
-
     for (unsigned int v=0; v<yres; ++v) {
       for (unsigned int u=0; u<xres; ++u) {
         // Pick a random sample group for surface points
@@ -127,6 +131,9 @@
           hidx[d]=static_cast<unsigned int>(ngroups*rng.gendrand());
 
         for (unsigned int s=0; s<nsamples; s += RayPacket::MaxSize) {
+          Real result=0;
+          Packet<Real> atten;
+
           // Initialize a ray packet
           int size=RayPacket::MaxSize;
           if (size >= nsamples - s) {
@@ -136,40 +143,40 @@
             size=nsamples - s;
           }
 
-          int depth=0;
-          int dlFlags=RayPacket::HaveHitPositions | RayPacket::HaveNormals |
-            RayPacket::HaveUnitNormals;
-
           RayPacketData raydata;
-          RayPacket rays(raydata, RayPacket::UnknownShape, 0, size, depth,
-                         dlFlags);
+          RayPacket rays(raydata, RayPacket::UnknownShape, 0, size, 0, 0);
 
           // Fill in the hit positions and surface normals at sample points
           for (int i=rays.begin(); i<rays.end(); ++i) {
             // Project surface sample point onto particle's surface
             Vector2D sample=sample_groups[sidx][s + i];
             
-            // Range of 2*M_PI*(u + sample.x)/xres --> [0, 2*Pi]
-            // Range of M_PI*(v + sample.y)/yres --> [0, Pi]
-            Real phi=2*M_PI*((u + sample.x()))*inv_xres;
-            Real theta=M_PI*((v + sample.y()))*inv_yres;
+            // Range of 2*M_PI*(u + sample.x)/(xres - 1) --> [0, 2*Pi]
+            // Range of M_PI*(v + sample.y)/(yres - 1) --> [0, Pi]
+            Real phi=2*M_PI*(u + sample.x())*inv_width;
+            Real theta=M_PI*(v + sample.y())*inv_height;
 
             Real x=cos(phi)*sin(theta);
             Real y=sin(phi)*sin(theta);
             Real z=cos(theta);
-            
-            Vector surface=center + radius*Vector(x, y, z);
-            Vector normal=(surface - center).normal();
-            // Vector normal=Vector(x, y, z).normal();
+
+            Vector normal(x, y, z);
+            Vector surface=center + radius*normal;
 
             rays.setHitPosition(i, surface);
             rays.setNormal(i, normal);
+            atten.set(i, 1);
           }
 
           // Iteratively trace the ray packet
-          Real result=0;
           for (unsigned int d=0; d<max_depth; ++d) {
+            // Reset ray packet flags
+            rays.setAllFlags(0);
+            rays.setFlag(RayPacket::HaveHitPositions | 
RayPacket::HaveNormals |
+                         RayPacket::HaveUnitNormals);
+
             // Compute direct lighting at current hit positions
+            const LightSet* activeLights=scene->getLights();
             ShadowAlgorithm::StateBuffer stateBuffer;
             bool firstTime=true;
             bool done;
@@ -184,7 +191,6 @@
               // 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.
-              const LightSet* activeLights=scene->getLights();
               done=rctx.shadowAlgorithm->computeShadows(rctx, activeLights,
                                                         rays, shadowRays,
                                                         firstTime,
@@ -193,24 +199,27 @@
               // Normalize directions for proper dot product computation
               shadowRays.normalizeDirections();
               
-              for (int i=shadowRays.begin(); i<shadowRays.end(); ++i) {
+              // XXX:  we're not actually getting shadows...
+              for (int i=shadowRays.begin(); i < shadowRays.end(); ++i) {
                 if (!shadowRays.wasHit(i)) {
-                  // Not in shadow, so compute the diffuse contribution
+                  // Not in shadow, so compute the direct contribution
                   Vector normal=rays.getNormal(i);
                   Vector shadowdir=shadowRays.getDirection(i);
                   ColorComponent cos_theta=Dot(shadowdir, normal);
                   Color light=shadowRays.getColor(i);
-                  result += light.luminance()*cos_theta;
+                  result += atten.get(i)*light.luminance()*cos_theta;
                 }
               }
               
               firstTime=false;
             } while(!done);
 
-#if 0
-            // XXX:  indirect is broken...  results in solid black textures
-            // Fill in the ray origins and directions
+            if (d >= max_depth - 1)
+              break;
+
+            // XXX:  not sure if this is correct...
             for (int i=rays.begin(); i<rays.end(); ++i) {
+              // Compute an ONB at the surface point
               Vector normal=rays.getNormal(i);
               Vector v0(Cross(normal, Vector(1,0,0)));
               if (v0.length2()==0)
@@ -219,9 +228,10 @@
               v0.normalize();
               v1.normalize();
 
+              // Generate a random direction in the hemisphere
               Vector2D hemi=sample_groups[hidx[d]][i];
               Real hphi=2.0*M_PI*hemi.x();
-              Real r=SCIRun::Sqrt(hemi.y());
+              Real hr=SCIRun::Sqrt(hemi.y());
               Real hx=r*cos(hphi);
               Real hy=r*sin(hphi);
               Real hz=SCIRun::Sqrt(1 - hx*hx - hy*hy);
@@ -230,9 +240,13 @@
               Vector dir=v0*out.x() + v1*out.y() + normal*out.z();
               dir.normalize();
 
-              // Set ray origin, direction
+              // Set ray origin and direction
               rays.setOrigin(i, rays.getHitPosition(i));
               rays.setDirection(i, dir);
+              
+              // Update attenutation
+              // XXX:  is this correct?
+              atten.set(i, atten.get(i)*Dot(normal, dir));
             }
 
             // Reset flags
@@ -243,7 +257,7 @@
             rays.resetHits();
             scene->getObject()->intersect(rctx, rays);
 
-            // Prep ray packet for next iteration
+            // Prepare ray packet for next iteration
             unsigned int validRays=0;
             for (unsigned int i=rays.begin(); i<rays.end();) {
               if (rays.wasHit(i)) {
@@ -263,6 +277,7 @@
                   if (dotprod>0) {
                     rays.setHitPosition(validRays, sub.getHitPosition(j));
                     rays.setNormal(validRays, sub.getNormal(j));
+                    atten.set(validRays, atten.get(i));
                     ++validRays;
                   } else {
                     // An invalid hit, resulting from:
@@ -282,16 +297,19 @@
 
                 i=end;
               } else {
-                // Find a run of rays that didn't hit anything and shade them
+                // Find a run of rays that didn't hit anything
                 unsigned int end=i + 1;
                 while (end < rays.end() && !rays.wasHit(end))
                   ++end;
+
+#if 0
+                // Shade them, and accumulate background color
                 RayPacket sub(rays, i, end);
                 scene->getBackground()->shade(rctx, sub);
 
-                // Accumulate background color
                 for (unsigned int j=i; j<end; ++j)
                   result += rays.getColor(j).luminance();
+#endif
 
                 i=end;
               }
@@ -304,12 +322,9 @@
             // Update the ray packet configuration, loop to next depth
             rays.setDepth(rays.getDepth() + 1);
             rays.resize(validRays);
-            rays.setAllFlags(0);
-            rays.setFlag(dlFlags);
-#endif
           }
 
-          // Store the normalized result
+          // Store the result
           dynplt->texture[u][v] += result;
         }
 

Modified: trunk/Model/Materials/DynPLTMaterial.cc
==============================================================================
--- trunk/Model/Materials/DynPLTMaterial.cc     (original)
+++ trunk/Model/Materials/DynPLTMaterial.cc     Fri May 19 14:15:52 2006
@@ -32,6 +32,9 @@
   // Do nothing
 }
 
+#include <iostream>
+using std::cerr;
+
 void DynPLTMaterial::shade(const RenderContext& context, RayPacket& rays) 
const
 {
   if (valid) {
@@ -43,76 +46,46 @@
     rays.computeTextureCoordinates2(context);
 
     for (unsigned int i=rays.begin(); i < rays.end(); ++i) {
-#if 1
+      // XXX:  there's still something subtle going on here..  not sure if 
it's
+      //       in x or y (but probably y); see bookmarked views in dynplt 
scene
+      // Wrap in x (assumes x is a power of two)
       Real x=rays.getTexCoords2(i, 0)*XRES;
-      int x_low=static_cast<int>(x);
-      Real x_weight = x - x_low;
-      // If low is negative then we need to look right (negative) for the 
high
-      // interpolant
-      int x_high;
-      if (x_low >= 0) {
-        x_high = x_low + 1;
-      } else {
-        x_high = x_low - 1;
-        // Here we get our negative index from [0..-size - 1].  Add size 
back in
-        // and you get the right shift.  You need to make sure you do the 
%size
-        // afterwards, though.  This will catch the case where
-        // low%size + size == size.
-        x_low  =  x_low%XRES + XRES;
-        x_high = x_high%XRES + XRES;
-
-        // If low was negative then weight will also be negative.  We don't
-        // need a negative number for interpolation.
-        x_weight = -x_weight;
-      }
+      int lx=static_cast<int>(x) & (XRES - 1);
+      int hx=(lx + 1) & (XRES - 1);
+      Real wx=x - lx;
       
-      x_low  %= XRES;
-      x_high %= XRES;
-      
-      Real y=rays.getTexCoords2(i, 1)*YRES;
-      int y_low=static_cast<int>(y);
-      Real y_weight = y - y_low;
-      // If low is negative then we need to look right (negative) for the 
high
-      // interpolant
-      int y_high;
-      if (y_low >= 0) {
-        y_high = y_low + 1;
+      // Clamp in y
+      Real y=rays.getTexCoords2(i, 1);
+      int ly;
+      Real wy;
+      if (y < 0) {
+        ly=0;
+        wy=0;
       } else {
-        y_high = y_low - 1;
-        // Here we get our negative index from [0..-size - 1].  Add size 
back in
-        // and you get the right shift.  You need to make sure you do the 
%size
-        // afterwards, though.  This will catch the case where
-        // low%size + size == size.
-        y_low  =  y_low%YRES + YRES;
-        y_high = y_high%YRES + YRES;
-
-        // If low was negative then weight will also be negative.  We don't
-        // need a negative number for interpolation.
-        y_weight = -y_weight;
-      }
-      
-      y_low  %= YRES;
-      y_high %= YRES;
+        y *= YRES - 1;
+        ly=static_cast<int>(y);
+#if 1
+        if (ly > YRES - 1) {
+          ly=YRES - 1;
 #else
-      // XXX:  This is broken (i.e., doesn't interpolate correctly).  Why?
-      Real x=rays.getTexCoords2(i, 0)*XRES;
-      int x_low=static_cast<int>(x) & (XRES - 1);
-      int x_high=x_low & (XRES-1);
-      Real x_weight=x - x_low;
-      
-      Real y=rays.getTexCoords2(i, 1)*YRES;
-      int y_low=static_cast<int>(y) & (YRES - 1);
-      int y_high=y_low & (YRES - 1);
-      Real y_weight=y - y_low;
-      // end XXX
+        if (ly > YRES - 2) {
+          ly=YRES - 2;
 #endif
-        
-      // Do the interpolation
-      Real a=(texture[x_low][y_low]   * (1 - x_weight) +
-              texture[x_high][y_low]  *      x_weight);
-      Real b=(texture[x_low][y_high]  * (1 - x_weight) +
-              texture[x_high][y_high] *      x_weight);
-      Real luminance=a*(1 - y_weight) + b*y_weight;
+          wy=0;
+        } else {
+          wy=y - ly;
+        }
+      }
+
+      int hy=ly + 1;
+      // end XXX
+
+      // Interpolate
+      Real a=(texture[lx][ly] * (1 - wx) +
+              texture[hx][ly] *      wx);
+      Real b=(texture[lx][hy] * (1 - wx) +
+              texture[hx][hy] *      wx);
+      Real luminance=a*(1 - wy) + b*wy;
 
       rays.setColor(i, diffuse.get(i)*luminance);
     }

Modified: trunk/Model/Primitives/Sphere.cc
==============================================================================
--- trunk/Model/Primitives/Sphere.cc    (original)
+++ trunk/Model/Primitives/Sphere.cc    Fri May 19 14:15:52 2006
@@ -391,8 +391,10 @@
     Vector n = (rays.getHitPosition(i)-center)*inv_radius;
     Real angle = Clamp(n.z(), (Real)-1, (Real)1);
     Real theta = Acos(angle);
-    Real phi = Atan2(n.x(), n.y());
-    Real x = (phi+(Real)M_PI)*((Real)0.5*M_1_PI);
+    Real phi = Atan2(n.y(), n.x());
+    Real x = phi*(Real)(0.5*M_1_PI);
+    if (x < 0)
+      x += 1;
     Real y = theta*(Real)M_1_PI;
     rays.setTexCoords(i, Vector(x, y, 0));
   }
@@ -407,8 +409,10 @@
     Vector n = (rays.getHitPosition(i)-center)*inv_radius;
     Real angle = Clamp(n.z(), (Real)-1, (Real)1);
     Real theta = Acos(angle);
-    Real phi = Atan2(n.x(), n.y());
-    Real x = (phi+(Real)M_PI)*((Real)0.5*M_1_PI);
+    Real phi = Atan2(n.y(), n.x());
+    Real x = phi*(Real)(0.5*M_1_PI);
+    if (x < 0)
+      x += 1;
     Real y = theta*(Real)M_1_PI;
     rays.setTexCoords(i, Vector(x, y, 0));
   }

Modified: trunk/scenes/dynplt.cc
==============================================================================
--- trunk/scenes/dynplt.cc      (original)
+++ trunk/scenes/dynplt.cc      Fri May 19 14:15:52 2006
@@ -32,6 +32,7 @@
   Group* world=0;
   string fname="";
   int max_depth=3;
+  int nsamples=32;
   int nthreads=1;
   double radius=1.;
   int ridx=-1;
@@ -50,6 +51,9 @@
     } else if (arg=="-i") {
       if (!getStringArg(i, args, fname))
         throw IllegalArgument("scene dynplt -i", i, args);
+    } else if (arg=="-nsamples") {
+      if (!getIntArg(i, args, nsamples))
+        throw IllegalArgument("scene dynplt -nsamples", i, args);
     } else if (arg=="-nthreads") {
       if (!getIntArg(i, args, nthreads))
         throw IllegalArgument("scene dynplt -nthreads", i, args);
@@ -83,7 +87,6 @@
   
   // Create DynPLTContext
   unsigned int ngroups=100; // XXX:  this should be a cmdln parameter
-  unsigned int nsamples=49; // XXX:  this should be a cmdln parameter
   DynPLTContext* dpltctx=new DynPLTContext(queue, scene, ngroups, nsamples,
                                            max_depth);
 
@@ -113,11 +116,13 @@
     if (ridx>=0)
       radius=pdata[idx + ridx];
     
+    // Material* dynplt=new DynPLTMaterial(queue, Color(RGB(1, 1, 1)));
     Material* dynplt=new DynPLTMaterial(queue, Color(RGB(1, 0, 0)));
     world->add(new Sphere(dynplt, Vector(x, y, z), radius));
   }
 
   // Initialize the scene
+  // scene->setBackground(new ConstantBackground(Color(RGB(0, 0, 0))));
   scene->setBackground(new ConstantBackground(Color(RGB(1, 1, 1))));
   scene->setObject(world);
 
@@ -127,12 +132,23 @@
   lights->setAmbientLight(new ConstantAmbient(Color(RGB(0.4, 0.4, 0.4))));
   scene->setLights(lights);
 
-  scene->addBookmark("default view", Vector(0.83, 0.85, 4.71),
+  scene->addBookmark("view 0", Vector(0.02, 1.02, 0.20),
+                     Vector(0.02, 0.02, 0.20), Vector(0, 0, 1),
+                     0.59);
+  scene->addBookmark("view 1", Vector(0.83, 0.85, 4.71),
                      Vector(0.02, 0.01, 0.29), Vector(-0.54, -0.58, 0.59),
                      0.59);
-  scene->addBookmark("another view", Vector(-0.83, 0.85, 4.71),
+  scene->addBookmark("view 2", Vector(-0.83, 0.85, 4.71),
                      Vector(0.02, 0.01, 0.29), Vector(-0.59, -0.59, 0.59),
                      0.59);
+  scene->addBookmark("broken interpolation 1",
+                     Vector(0.25853, 0.146471, 1.16313),
+                     Vector(0.0207405, 0.0211326, 0.199939),
+                     Vector(-0.539328, -0.80769, 0.238249), 0.0132616);
+  scene->addBookmark("broken interpolation 2",
+                     Vector(0.00145609, 0.584749, 1.02512),
+                     Vector(0.0208755, 0.020066, 0.200044),
+                     Vector(-0.362337, -0.773111, 0.520588), 0.0709904);
 
   return scene;
 }




  • [MANTA] r1076 - in trunk: Engine/Control Model/Materials Model/Primitives scenes, cgribble, 05/19/2006

Archive powered by MHonArc 2.6.16.

Top of page