Text archives Help
- 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.