Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[Manta] r2016 - trunk/Engine/Renderers


Chronological Thread 
  • From: roni@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [Manta] r2016 - trunk/Engine/Renderers
  • Date: Mon, 28 Jan 2008 23:37:14 -0700 (MST)

Author: roni
Date: Mon Jan 28 23:37:13 2008
New Revision: 2016

Modified:
   trunk/Engine/Renderers/NPREdges.cc
   trunk/Engine/Renderers/NPREdges.h
Log:
Revamped edge line drawing algorithm- now the scene is drawn as normal
(using a Manta::Raytracer), and then the edge lines are composited on
top with a second pass.  This enables anti-aliasing for edge lines.

Added -noshade option, which makes the framebuffer all-white before
beginning the second pass mentioned above.  Helpful for debugging, and
can look cool with certain scenes ;)

Committing this revision in preparation for a major change in the way
this module works.


Modified: trunk/Engine/Renderers/NPREdges.cc
==============================================================================
--- trunk/Engine/Renderers/NPREdges.cc  (original)
+++ trunk/Engine/Renderers/NPREdges.cc  Mon Jan 28 23:37:13 2008
@@ -24,7 +24,8 @@
   : raytracer(new Raytracer),
     imageX(0.0), imageY(0.0),
     lineWidth(1.0), normalThreshold(0.0),
-    computeCreases(true)
+    computeCreases(true),
+    noshade(false)
 {
   bool threshold_set = false;
 
@@ -45,6 +46,9 @@
     else if(arg == "-nocrease"){
       computeCreases = false;
     }
+    else if(arg == "-noshade"){
+      noshade = true;
+    }
     else {
       throw IllegalArgument("NPREdges", i, args);
     }
@@ -92,11 +96,23 @@
 void NPREdges::traceRays(const RenderContext& context, RayPacket& rays)
 {
   const int debugFlag = rays.getAllFlags() & RayPacket::DebugPacket;
-  if(debugFlag)
-    cerr << "debug ray" << endl;
 
-  rays.resetHits();
-  context.scene->getObject()->intersect(context, rays);
+  // Shade the scene as normal (NPR lines will go as an overlay on
+  // top).  Create a render context for default shading.
+  RenderContext subContext(context.rtrt_int,
+                          context.channelIndex, context.proc, 
context.numProcs,
+                          context.frameState,
+                          context.loadBalancer, context.pixelSampler,
+                          raytracer, context.shadowAlgorithm,
+                          context.camera, context.scene,
+                          context.storage_allocator,
+                          context.rng,
+                          context.sample_generator);
+  raytracer->traceRays(subContext, rays);
+
+  if(noshade)
+    for(int i=rays.begin(); i<rays.end(); i++)
+      rays.setColor(i, Color::white());
 
   // Create parallel ray packets, each containing one member of a
   // "surround" for each ray in the rays parameter.
@@ -118,18 +134,6 @@
 
   const unsigned surroundSize = sizeof(surround)/sizeof(surround[0]);
 
-  // If we need to do actual shading, we'll need to use a Raytracer,
-  // so create a temporary RenderContext.
-  RenderContext subContext(context.rtrt_int,
-                          context.channelIndex, context.proc, 
context.numProcs,
-                          context.frameState,
-                          context.loadBalancer, context.pixelSampler,
-                          raytracer, context.shadowAlgorithm,
-                          context.camera, context.scene,
-                          context.storage_allocator,
-                          context.rng,
-                          context.sample_generator);
-
   // Populate the surround packets' image coordinates.
   for(int i=rays.begin(); i<rays.end(); i++){
     int eye = rays.getWhichEye(i);
@@ -149,114 +153,63 @@
     context.scene->getObject()->intersect(context, *surround[i]);
   }
 
-  for(int i=rays.begin(); i<rays.end(); ){
-    switch(type(rays, surround, i)){
-    case Background:
+  for(int i=rays.begin(); i<rays.end(); i++){
+    int count;
+
+    switch(type(rays, surround, i, count)){
+    case Intersection:
       {
-       int j=i+1;
-       while(j < rays.end() && type(rays, surround, j) == Background)
-         ++j;
-       RayPacket subPacket(rays, i, j);
-       context.scene->getBackground()->shade(subContext, subPacket);
-       i = j;
+        if(debugFlag)
+          cerr << "count was " << count << endl;
+
+        float lightness = abs(count - 2) / 2.0;
+        rays.setColor(i, rays.getColor(i)*lightness);
       }
       break;
 
-    case Shade:
+    case Background:
       {
-       const Primitive *hit = rays.getHitPrimitive(i);
-       const Material *matl = rays.getHitMaterial(i);
-       int j=i+1;
-       while(j < rays.end() && type(rays, surround, j) == Shade && 
rays.getHitPrimitive(j) == hit)
-         ++j;
-
-       if(!computeCreases){
-         RayPacket subPacket(rays, i, j);
-         matl->shade(subContext, subPacket);
-       }
-       else{
-         // Handle crease edges here.
-         RayPacket normRight(surrRight, i, j);
-         RayPacket normLeft(surrLeft, i, j);
-         RayPacket normUp(surrUp, i, j);
-         RayPacket normDown(surrDown, i, j);
-
-         normRight.computeFFNormals(context);
-         normLeft.computeFFNormals(context);
-         normUp.computeFFNormals(context);
-         normDown.computeFFNormals(context);
-
-         // Process the section of the ray packet between i and j -
-         // this section contains samples that all struck the same
-         // primitive.  The task is to find any crease line samples
-         // and mark them black, while shading the rest with the
-         // normal ray tracer.
-         int m=i, n=i+1;
-         while(m<j){
-           // This loop looks for a sequence of crease samples.
-           while(m<j){
-             Vector v1 = normRight.getNormal(m) - normLeft.getNormal(m);
-             Vector v2 = normUp.getNormal(m) - normDown.getNormal(m);
-       
-             if(v1.length2() + v2.length2() > normalThreshold){
-               rays.setColor(m, Color(RGBColor(0,0,0)));
-               ++m;
-             }
-             else{
-               break;
-             }
-           }
-
-           // If the stretch of crease samples reaches to the end of
-           // the sub packet, we are done.
-           if(m == j)
-             break;
-
-           // Start looking for a stretch of non-crease samples right
-           // after the crease samples.
-           n = m+1;
-           while(n<j){
-             Vector v1 = normRight.getNormal(n) - normLeft.getNormal(n);
-             Vector v2 = normUp.getNormal(n) - normDown.getNormal(n);
-
-             if(v1.length2() + v2.length2() > normalThreshold){
-               // When a crease sample is found, shade the non crease
-               // samples and break out of the loop.
-               rays.setColor(n, Color(RGBColor(0,0,0)));
-               RayPacket subPacket(rays, m, n);
-               matl->shade(subContext, subPacket);
-               break;
-             }
-             else{
-               ++n;
-             }
-           }
-
-           // If we reached the end of the sub packet, shade the
-           // samples.  The loop condition will break us out of this
-           // loop.
-           if(n == j){
-             RayPacket subPacket(rays, m, n);
-             matl->shade(subContext, subPacket);
-           }
-
-           m = n+1;
-         }
-       }
-
-       i = j;
+        if(debugFlag)
+          cerr << "Ray is background all-surround" << endl;
       }
       break;
 
-    case Intersection:
+    case Shade:
       {
-       rays.setColor(i, Color(RGBColor(0,0,0)));
-       ++i;
+        if(debugFlag)
+          cerr << "Ray is primitive all-surround" << endl;
+
+        // Check for crease line.
+        RayPacket normRight(surrRight, i, i+1);
+        RayPacket normLeft(surrLeft, i, i+1);
+        RayPacket normUp(surrUp, i, i+1);
+        RayPacket normDown(surrDown, i, i+1);
+
+        normRight.computeFFNormals(context);
+        normLeft.computeFFNormals(context);
+        normUp.computeFFNormals(context);
+        normDown.computeFFNormals(context);
+
+        const Vector v1 = normRight.getFFNormal(i) - normLeft.getFFNormal(i);
+        const Vector v2 = normUp.getFFNormal(i) - normDown.getFFNormal(i);
+
+        if(debugFlag){
+          cerr << "right normal: " << normRight.getFFNormal(i) << endl
+               << "left normal: " << normLeft.getFFNormal(i) << endl
+               << "up normal: " << normUp.getFFNormal(i) << endl
+               << "down normal: " << normDown.getFFNormal(i) << endl
+               << "v1 (right minus left): " << v1 << endl
+               << "v2 (right minus left): " << v2 << endl;
+        }
+
+        if(v1.length2() + v2.length2() > normalThreshold){
+          rays.setColor(i, Color::black());
+        }
       }
       break;
     }
   }
-}       
+}
 
 void NPREdges::traceRays(const RenderContext& context, RayPacket& rays, Real)
 {
@@ -276,6 +229,37 @@
     for(int j=0; j<4; j++)
       if(surround[j]->wasHit(i))
        return Intersection;
+    
+    // If all the surround rays strike the background, this is a background 
sample.
+    return Background;
+  }
+
+  // If we reach here, the sample ray struck a primitive, and so did
+  // all the surround rays.
+  return Shade;
+}
+
+NPREdges::PixelType NPREdges::type(const RayPacket& sample, const RayPacket 
*const surround[], int i, int& count) const {
+  if(sample.wasHit(i)){
+    // The sample ray hit a primitive; check if this is an intersection 
sample.
+    count = 0;
+    const Primitive *hit = sample.getHitPrimitive(i);
+    for(int j=0; j<4; j++)
+      if(!(surround[j]->wasHit(i) && (surround[j]->getHitPrimitive(i) == 
hit))){
+        ++count;
+      }
+    if(count > 0)
+      return Intersection;
+  }
+  else{
+    // The sample ray struck the background; check if this is an 
intersection sample.
+    count = 0;
+    for(int j=0; j<4; j++)
+      if(surround[j]->wasHit(i))
+        ++count;
+
+    if(count > 0)
+      return Intersection;
     
     // If all the surround rays strike the background, this is a background 
sample.
     return Background;

Modified: trunk/Engine/Renderers/NPREdges.h
==============================================================================
--- trunk/Engine/Renderers/NPREdges.h   (original)
+++ trunk/Engine/Renderers/NPREdges.h   Mon Jan 28 23:37:13 2008
@@ -39,12 +39,13 @@
     } PixelType ;
 
     PixelType type(const RayPacket& sample, const RayPacket *const 
surround[], int i) const;
+    PixelType type(const RayPacket& sample, const RayPacket *const 
surround[], int i, int& count) const;
 
     Raytracer *raytracer;
 
     Real imageX, imageY;
     Real lineWidth, normalThreshold;
-    bool computeCreases;
+    bool computeCreases, noshade;
 
   private:
     NPREdges(const NPREdges&);





Archive powered by MHonArc 2.6.16.

Top of page