Text archives Help
- 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&);
- [Manta] r2016 - trunk/Engine/Renderers, roni, 01/29/2008
Archive powered by MHonArc 2.6.16.