Text archives Help
- From: sparker@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [Manta] r1868 - trunk/Engine/Renderers
- Date: Mon, 26 Nov 2007 07:41:20 -0700 (MST)
Author: sparker
Date: Mon Nov 26 07:40:59 2007
New Revision: 1868
Modified:
trunk/Engine/Renderers/KajiyaPathtracer.cc
trunk/Engine/Renderers/KajiyaPathtracer.h
Log:
Added a framework for experimenting with various pathtracing options.
Current mode
is one bounce plus ambient.
Modified: trunk/Engine/Renderers/KajiyaPathtracer.cc
==============================================================================
--- trunk/Engine/Renderers/KajiyaPathtracer.cc (original)
+++ trunk/Engine/Renderers/KajiyaPathtracer.cc Mon Nov 26 07:40:59 2007
@@ -1,11 +1,6 @@
-// TODO
-// Need to determine light area and normal
-// If single pixel, use a single accumulator
-// Put background rays at end to make alignment easier - DO BACKGROUND RAYS
ALL AT ONCE!!!
-// Try sorting after MC by direction/origin and do not sort by matl
-// shadow rays with important sampling?
-// Russian roulette for shadow rays?
+
#include <Engine/Renderers/KajiyaPathtracer.h>
+#include <Engine/Shadows/NoDirect.h>
#include <Interface/Background.h>
#include <Interface/Camera.h>
#include <Interface/Context.h>
@@ -32,6 +27,22 @@
KajiyaPathtracer::KajiyaPathtracer(const vector<string>& /*args*/)
{
+ ambient_only_sa = new NoDirect();
+ override_maxdepth = -1;
+ // No presorting, since none are implemented yet.
+ presort_mode.push_back(PreSortNone);
+
+ // Full sort on materials
+ matlsort_mode.push_back(MatlSortBackgroundSweep);
+ matlsort_mode.push_back(MatlSortSweep);
+ matlsort_mode.push_back(MatlSortFull);
+
+ // Do RR only after the first bounce
+ russian_roulette_mode.push_back(RussianRouletteNone);
+ russian_roulette_mode.push_back(RussianRouletteFull);
+
+ do_ambient_on_maxdepth = true;
+ override_maxdepth = 2;
}
KajiyaPathtracer::~KajiyaPathtracer()
@@ -63,6 +74,41 @@
array[j] = tmp;
}
+/*
+
+ Basic algorithm:
+
+ while there are active rays and depth < maxdepth
+ 1. Pre-sort rays in the packet according to some criteria
+ Options for each depth
+ a. No sort
+ b. Sort using a space filling curve on origin (not implemented yet)
+ c. Sort using a space filling curve on direction (not implemented yet)
+ d. Sort using a space filling curve in 5D
+ 2. intersect
+ 3. Sort on materials, separating background rays
+ Options for each depth
+ a. Only partition out background rays
+ b. Group identical materials based on a sweep
+ c. Full sort on material
+ 4. compute new rays and reflectance
+ 5. compute direct light
+ 6. Russian roulete to kill rays
+ Options for each depth
+ a. No russian roulette
+ b. Full russian roulette
+
+ After the loop:
+ (optional) for remaining rays, compute ambient light
+ compute background for all rays that struck the background
+
+ Presort (step 1), material sort (step 3), and russian roulette (step 4)
can all be controlled
+ per depth with the presort, matlsort, and russian_roulette arrays,
respectively. Each array
+ contains an enum with the option for that depth. If the depth is larger
than the array, the
+ last element is used.
+
+*/
+
void KajiyaPathtracer::traceEyeRays(const RenderContext& context, RayPacket&
rays)
{
ASSERT(rays.getFlag(RayPacket::HaveImageCoordinates));
@@ -86,101 +132,78 @@
RayPacketData* data = rays.data;
int depth = 0;
- int maxdepth = context.scene->getRenderParameters().maxDepth;
+ int maxdepth = override_maxdepth >= 0?
override_maxdepth:context.scene->getRenderParameters().maxDepth;
for(;;){
+ // 1. Pre-sort rays in the packet according to some criteria
+ PreSortMode psm = depth >=
static_cast<int>(presort_mode.size())?presort_mode[presort_mode.size()-1]:presort_mode[depth];
+ switch(psm){
+ case PreSortOrigin:
+ presort_origin(context, rays, result, total_attenuation, permute);
+ break;
+ case PreSortDirection:
+ presort_direction(context, rays, result, total_attenuation, permute);
+ break;
+ case PreSort5D:
+ presort_5d(context, rays, result, total_attenuation, permute);
+ break;
+ case PreSortNone:
+ default:
+ // Do nothing
+ break;
+ }
+
+ // 2. intersect
rays.resetHits();
context.scene->getObject()->intersect(context, rays);
+ rays.computeHitPositions();
+ rays.safeComputeNormals(context);
+ rays.computeFFNormals(context); // Must do this before writing over the
ray direction
- // Sort the rays based on the material that they hit
- // Simple bubble sort for now - performance will come later
- // This may not be worthwhile if we sort by directions, but
- // we would still need to sort out the background rays (one pass)
- // Another option is to use a sort that picks one unique value and then
- // searches for all pointers of this type. It could probably be SSEd.
- for(int i=rays.begin();i<rays.end()-1;i++){
- for(int j=i+1;j<rays.end();j++){
- if(sort_needs_swap(data, i, j)){
- // Move hitPrim, hitMatl, hitTex, origin, direction, minT, time
- swap(data->hitPrim, i, j);
- swap(data->hitMatl, i, j);
- swap(data->hitTex, i, j);
- for(int k=0;k<3;k++)
- swap(data->origin[k], i, j);
- for(int k=0;k<3;k++)
- swap(data->direction[k], i, j);
- swap(data->minT, i, j);
- swap(data->time, i, j);
-
- // Conditionally: normal
- for(int k=0;k<3;k++)
- swap(data->normal[k], i, j);
-
- // Conditionally: ffnormal,
- for(int k=0;k<3;k++)
- swap(data->ffnormal[k], i, j);
-
- // Conditionally: hitPosition,
- for(int k=0;k<3;k++)
- swap(data->hitPosition[k], i, j);
-
- // Conditionally: texCoords, dPdu, dpDv
- for(int k=0;k<3;k++)
- swap(data->texCoords[k], i, j);
- for(int k=0;k<3;k++)
- swap(data->dPdu[k], i, j);
- for(int k=0;k<3;k++)
- swap(data->dPdv[k], i, j);
-
- // Move sample_id, region_id
- swap(data->sample_id, i, j);
- swap(data->region_id, i, j);
-
- // Move scratchpads???
- // Move result
- for(int k=0;k<3;k++)
- swap(result.colordata[k], i, j);
-
- // Move total attenuation
- for(int k=0;k<3;k++)
- swap(total_attenuation.colordata[k], i, j);
-
- // Move permute
- swap(permute.data, i, j);
- }
- }
+ // 3. Sort on materials, separating background rays
+ MatlSortMode msm = depth >=
static_cast<int>(matlsort_mode.size())?matlsort_mode[matlsort_mode.size()-1]:matlsort_mode[depth];
+ switch(msm){
+ case MatlSortSweep:
+ matlsort_sweep(context, rays, result, total_attenuation, reflectance,
permute);
+ break;
+ case MatlSortFull:
+ matlsort_full(context, rays, result, total_attenuation, permute);
+ break;
+ case MatlSortBackgroundSweep:
+ default:
+ matlsort_bgsweep(context, rays, result, total_attenuation, permute);
+ break;
}
- // Skip background rays - they will be shaded all at once below
- int newBegin = rays.begin();
- while(!rays.wasHit(newBegin))
- newBegin++;
- rays.resize(newBegin, rays.end());
if(rays.begin() == rays.end())
break;
-
- // Clear inverseDirection, corner_dir, signs
- rays.flags &= ~(RayPacket::HaveCornerRays |
RayPacket::HaveInverseDirections | RayPacket::HaveSigns);
-
- rays.computeHitPositions();
- rays.computeFFNormals(context); // Must do this before writing over the
ray direction
-
- // Compute new rays and reflectance for anything that hit a surface
- for(int i = rays.begin();i<rays.end();){
- const Material* hit_matl = rays.getHitMaterial(i);
- int end = i+1;
- while(end < rays.end() && rays.getHitMaterial(end) == hit_matl)
- end++;
- RayPacket subPacket(rays, i, end);
- hit_matl->sampleBSDF(context, subPacket, reflectance);
- i=end;
+
+ // 4. compute new rays and reflectance
+ // For MatlSortSweep, this was already done simultaneous with sorting
+ if(msm != MatlSortSweep){
+ for(int i = rays.begin();i<rays.end();){
+ const Material* hit_matl = rays.getHitMaterial(i);
+ int end = i+1;
+ while(end < rays.end() && rays.getHitMaterial(end) == hit_matl)
+ end++;
+ RayPacket subPacket(rays, i, end);
+ hit_matl->sampleBSDF(context, subPacket, reflectance);
+ i=end;
+ }
}
+ // Propagate reflectance
for(int i=rays.begin();i<rays.end();i++){
for(int j=0;j<3;j++)
total_attenuation.colordata[j][i] *= reflectance.colordata[j][i];
}
- // Cast shadow rays
+ rays.flags &= ~(RayPacket::HaveCornerRays |
RayPacket::HaveInverseDirections | RayPacket::HaveSigns);
+ // For now, assume that the rays coming out of sampleBSDF are unit
length. With
+ // transformations, this may not be true, so consider gathering the unit
length
+ // flags from sampleBSDF above
+ rays.flags |= RayPacket::NormalizedDirections;
+
+ // 5. compute direct light
ShadowAlgorithm::StateBuffer shadowState;
do {
RayPacketData shadowData;
@@ -200,7 +223,6 @@
// Not in shadow, so compute the direct lighting contributions.
Vector normal = rays.getFFNormal(i);
Vector light_dir = shadowRays.getDirection(i);
- light_dir.normalize();
double weight=Dot(normal, light_dir);
Color light_color = shadowRays.getColor(i);
result.set(i, result.get(i) + total_attenuation.get(i) *
light_color * weight);
@@ -208,83 +230,50 @@
}
} while(!shadowState.done());
- // Russian roulette and collapse
- bool do_russian_roulette = (depth > 0);
- if(do_russian_roulette){
- Packet<Real> rr;
- context.sample_generator->nextSeeds(context, rr, rays);
- int newEnd = rays.end();
- for(int i=rays.begin();i<newEnd;i++){
- double max = reflectance.get(i).maxComponent();
- if(rr.get(i) > max){
- // Kill it by swapping with the last ray
- // We may not need to move origin/direction back....
- --newEnd;
- // Move origin, direction
- // Look at one-way move optimization
- for(int j=0;j<3;j++)
- swap(data->origin[j], i, newEnd);
- for(int j=0;j<3;j++)
- swap(data->direction[j], i, newEnd);
-
- // Move ffnormal
- for(int j=0;j<3;j++)
- swap(data->ffnormal[j], i, newEnd);
-
- // Move hitPosition
- for(int j=0;j<3;j++)
- swap(data->hitPosition[j], i, newEnd);
-
- // Move time
- // Look at one-way move optimization
- swap(data->time, i, newEnd);
-
- // Move sample_id, region_id
- // Look at one-way move optimization
- swap(data->sample_id, i, newEnd);
- swap(data->region_id, i, newEnd);
-
- // Move result
- for(int j=0;j<3;j++)
- swap(result.colordata[j], i, newEnd);
-
- // Move reflectance
- // Look at one-way move optimization
- for(int j=0;j<3;j++)
- swap(reflectance.colordata[j], i, newEnd);
-
- // Move total attenuation
- // Look at one-way move optimization
- for(int j=0;j<3;j++)
- swap(total_attenuation.colordata[j], i, newEnd);
-
- // Move rr
- // Look at one-way move optimization
- swap(rr.data, i, newEnd);
-
- // Move permute
- swap(permute.data, i, newEnd);
-
- --i;
- } else {
- Real scale = Real(1.)/max;
- for(int j=0;j<3;j++)
- reflectance.colordata[j][i] *= scale;
- for(int j=0;j<3;j++)
- total_attenuation.colordata[j][i] *= scale;
- }
-
- rays.resize(rays.begin(), newEnd);
- if(rays.begin() == rays.end())
- break;
- }
+ // 6. Russian roulete to kill rays
+ RussianRouletteMode rrm = depth >=
static_cast<int>(russian_roulette_mode.size())?russian_roulette_mode[russian_roulette_mode.size()-1]:russian_roulette_mode[depth];
+ switch(rrm){
+ case RussianRouletteFull:
+ if(depth != maxdepth-1)
+ russian_roulette_full(context, rays, result, total_attenuation,
reflectance, permute);
+ break;
+ case RussianRouletteNone:
+ default:
+ // Do nothing
+ break;
}
+ if(rays.begin() == rays.end())
+ break;
depth++;
if(depth >= maxdepth)
break;
- rays.flags &= RayPacket::ConstantEye | RayPacket::ConstantPixel |
RayPacket::ConstantSampleRegion;
+ rays.flags &= RayPacket::ConstantEye | RayPacket::ConstantPixel |
RayPacket::ConstantSampleRegion | RayPacket::NormalizedDirections;
+ rays.shape = RayPacket::UnknownShape;
+ }
+
+ // Add ambient contribution for any remaining rays
+ if(do_ambient_on_maxdepth){
+ // Should there be an option here for doing a sweep/sort on the
remaining rays???
+ ShadowAlgorithm* save_sa = context.shadowAlgorithm;
+ // Sneaky ugly cast-away-const. Consider making RenderContext not const
for this reason
+ const_cast<RenderContext&>(context).shadowAlgorithm = ambient_only_sa;
+ for(int i = rays.begin();i<rays.end();){
+ const Material* hit_matl = rays.getHitMaterial(i);
+ int end = i+1;
+ while(end < rays.end() && rays.getHitMaterial(end) == hit_matl)
+ end++;
+ RayPacket subPacket(rays, i, end);
+ hit_matl->shade(context, subPacket);
+ i=end;
+ }
+ const_cast<RenderContext&>(context).shadowAlgorithm = save_sa;
+
+ for(int i = rays.begin(); i < rays.end(); i++){
+ for(int j=0;j<3;j++)
+ result.colordata[j][i] += data->color[j][i] *
total_attenuation.colordata[j][i];
+ }
}
// Add contribution from background rays, which will be at the beginning.
@@ -301,13 +290,336 @@
rays.resetHits();
rays.flags &= RayPacket::ConstantEye | RayPacket::ConstantPixel |
RayPacket::ConstantSampleRegion;
rays.flags |= RayPacket::NormalizedDirections;
- rays.shape = RayPacket::UnknownShape;
for(int i=rays.begin();i<rays.end();i++){
rays.setColor(permute.get(i), result.get(i));
}
}
+
+void KajiyaPathtracer::matlsort_full(const RenderContext& context,
RayPacket& rays,
+ Packet<Color>& result,
+ Packet<Color>& total_attenuation,
+ Packet<int>& permute)
+{
+ // Sort the rays based on the material that they hit
+ // Simple bubble sort for now - performance will come later
+ // This may not be worthwhile if we sort by directions, but
+ // we would still need to sort out the background rays (one pass)
+ // Another option is to use a sort that picks one unique value and then
+ // searches for all pointers of this type. It could probably be SSEd.
+ RayPacketData* data = rays.data;
+ for(int i=rays.begin();i<rays.end()-1;i++){
+ for(int j=i+1;j<rays.end();j++){
+ if(sort_needs_swap(data, i, j)){
+ // Move hitPrim, hitMatl, hitTex, origin, direction, minT, time
+ swap(data->hitPrim, i, j);
+ swap(data->hitMatl, i, j);
+ swap(data->hitTex, i, j);
+ for(int k=0;k<3;k++)
+ swap(data->origin[k], i, j);
+ for(int k=0;k<3;k++)
+ swap(data->direction[k], i, j);
+ swap(data->minT, i, j);
+ swap(data->time, i, j);
+
+ // Conditionally: normal
+ for(int k=0;k<3;k++)
+ swap(data->normal[k], i, j);
+
+ // Conditionally: ffnormal,
+ for(int k=0;k<3;k++)
+ swap(data->ffnormal[k], i, j);
+
+ // Conditionally: hitPosition,
+ for(int k=0;k<3;k++)
+ swap(data->hitPosition[k], i, j);
+
+ // Conditionally: texCoords, dPdu, dpDv
+ // Perhaps these do not need to be moved???
+ for(int k=0;k<3;k++)
+ swap(data->texCoords[k], i, j);
+ for(int k=0;k<3;k++)
+ swap(data->dPdu[k], i, j);
+ for(int k=0;k<3;k++)
+ swap(data->dPdv[k], i, j);
+
+ // Move sample_id, region_id
+ swap(data->sample_id, i, j);
+ swap(data->region_id, i, j);
+
+ // Move result
+ for(int k=0;k<3;k++)
+ swap(result.colordata[k], i, j);
+
+ // Move total attenuation
+ for(int k=0;k<3;k++)
+ swap(total_attenuation.colordata[k], i, j);
+
+ // Move permute
+ swap(permute.data, i, j);
+ }
+ }
+ }
+ // Pull out background rays - they will be shaded all at once below
+ int newBegin = rays.begin();
+ while(newBegin < rays.end() && !rays.wasHit(newBegin))
+ newBegin++;
+ rays.resize(newBegin, rays.end());
+}
+
+void KajiyaPathtracer::russian_roulette_full(const RenderContext& context,
RayPacket& rays,
+ Packet<Color>& result,
+ Packet<Color>&
total_attenuation,
+ Packet<Color>& reflectance,
+ Packet<int>& permute)
+{
+ Packet<Real> rr;
+ context.sample_generator->nextSeeds(context, rr, rays);
+ RayPacketData* data = rays.data;
+
+ int newEnd = rays.end()-1;
+ while(newEnd >= rays.begin() && rr.get(newEnd) >=
reflectance.get(newEnd).maxComponent())
+ newEnd--;
+
+ for(int i=rays.begin();i<=newEnd;i++){
+ double max = reflectance.get(i).maxComponent();
+ if(rr.get(i) > max){
+ // Kill it by swapping with the last ray
+ // We may not need to move origin/direction back....
+ // Move origin, direction
+ // Look at one-way move optimization
+ for(int j=0;j<3;j++)
+ swap(data->origin[j], i, newEnd);
+ for(int j=0;j<3;j++)
+ swap(data->direction[j], i, newEnd);
+
+ // Move ffnormal
+ for(int j=0;j<3;j++)
+ swap(data->ffnormal[j], i, newEnd);
+
+ // Move hitPosition
+ for(int j=0;j<3;j++)
+ swap(data->hitPosition[j], i, newEnd);
+
+ // Move time
+ // Look at one-way move optimization
+ swap(data->time, i, newEnd);
+
+ // Move sample_id, region_id
+ // Look at one-way move optimization
+ swap(data->sample_id, i, newEnd);
+ swap(data->region_id, i, newEnd);
+
+ // Move result
+ for(int j=0;j<3;j++)
+ swap(result.colordata[j], i, newEnd);
+
+ // Move reflectance
+ // Look at one-way move optimization
+ for(int j=0;j<3;j++)
+ swap(reflectance.colordata[j], i, newEnd);
+
+ // Move total attenuation
+ // Look at one-way move optimization
+ for(int j=0;j<3;j++)
+ swap(total_attenuation.colordata[j], i, newEnd);
+
+ // Move rr
+ // Look at one-way move optimization
+ swap(rr.data, i, newEnd);
+
+ // Move permute
+ swap(permute.data, i, newEnd);
+
+ i--;
+ newEnd--;
+ while(newEnd > i && rr.get(newEnd) >=
reflectance.get(newEnd).maxComponent())
+ newEnd--;
+ }
+ }
+ for(int i=newEnd+1;i<rays.end();i++){
+ float max = reflectance.get(i).maxComponent();
+ Real scale = Real(1.)/max;
+ for(int j=0;j<3;j++)
+ reflectance.colordata[j][i] *= scale;
+ for(int j=0;j<3;j++)
+ total_attenuation.colordata[j][i] *= scale;
+ }
+
+ rays.resize(rays.begin(), newEnd+1);
+}
+
+void KajiyaPathtracer::presort_origin(const RenderContext&, RayPacket&,
Packet<Color>&, Packet<Color>&, Packet<int>&)
+{
+ NOT_FINISHED("KajiyaPathtracer::traceEyeRays");
+}
+
+void KajiyaPathtracer::matlsort_sweep(const RenderContext& context,
RayPacket& rays,
+ Packet<Color>& result,
+ Packet<Color>& total_attenuation,
+ Packet<Color>& reflectance,
+ Packet<int>& permute)
+{
+ matlsort_bgsweep(context, rays, result, total_attenuation, permute);
+ // Sort the rays into two groups - those that hit an object
+ // and those that hit the background. The background rays should
+ // be first, so those are processed first by the bgsweep.
+ // Technically, this is O(N^2), but if there are relatively few unique
+ // materials in an average packet, this should perform pretty well.
+ // We try to minimize movement of rays wherever possible.
+ RayPacketData* data = rays.data;
+ for(int i=rays.begin(); i < rays.end();){
+ const Material* matl = data->hitMatl[i];
+ int begin = i;
+ i++;
+
+ // Skip to find the next hole
+ while(i < rays.end() && data->hitMatl[i] == matl)
+ i++;
+
+ // Find any other rays that also hit that material. Start from the end
so that
+ // We can fill in gaps and minimize the total number of moves in many
cases
+ for(int j=rays.end()-1;j>=i+1;j--){
+ // Skip over all of the rays that hit the same material
+ if(data->hitMatl[j] == matl){
+ // Move hitPrim, hitMatl, hitTex, origin, direction, minT, time
+ swap(data->hitPrim, i, j);
+ swap(data->hitMatl, i, j);
+ swap(data->hitTex, i, j);
+ for(int k=0;k<3;k++)
+ swap(data->origin[k], i, j);
+ for(int k=0;k<3;k++)
+ swap(data->direction[k], i, j);
+ swap(data->minT, i, j);
+ swap(data->time, i, j);
+
+ // Conditionally: normal
+ for(int k=0;k<3;k++)
+ swap(data->normal[k], i, j);
+
+ // Conditionally: ffnormal,
+ for(int k=0;k<3;k++)
+ swap(data->ffnormal[k], i, j);
+
+ // Conditionally: hitPosition,
+ for(int k=0;k<3;k++)
+ swap(data->hitPosition[k], i, j);
+
+ // Conditionally: texCoords, dPdu, dpDv
+ // Perhaps these do not need to be moved???
+ for(int k=0;k<3;k++)
+ swap(data->texCoords[k], i, j);
+ for(int k=0;k<3;k++)
+ swap(data->dPdu[k], i, j);
+ for(int k=0;k<3;k++)
+ swap(data->dPdv[k], i, j);
+
+ // Move sample_id, region_id
+ swap(data->sample_id, i, j);
+ swap(data->region_id, i, j);
+
+ // Move result
+ for(int k=0;k<3;k++)
+ swap(result.colordata[k], i, j);
+
+ // Move total attenuation
+ for(int k=0;k<3;k++)
+ swap(total_attenuation.colordata[k], i, j);
+
+ // Move permute
+ swap(permute.data, i, j);
+ i++;
+ // Find another hole
+ while(i <= j && data->hitMatl[i] == matl)
+ i++;
+ }
+ }
+ RayPacket subPacket(rays, begin, i);
+ matl->sampleBSDF(context, subPacket, reflectance);
+ }
+}
+
+void KajiyaPathtracer::presort_direction(const RenderContext&, RayPacket&,
Packet<Color>&, Packet<Color>&, Packet<int>&)
+{
+ NOT_FINISHED("KajiyaPathtracer::presort_direction");
+}
+
+void KajiyaPathtracer::presort_5d(const RenderContext&, RayPacket&,
Packet<Color>&, Packet<Color>&, Packet<int>&)
+{
+ NOT_FINISHED("KajiyaPathtracer::presort_5d");
+}
+
+void KajiyaPathtracer::matlsort_bgsweep(const RenderContext&, RayPacket&
rays,
+ Packet<Color>& result,
+ Packet<Color>& total_attenuation,
+ Packet<int>& permute)
+{
+ // Sort the rays into two groups - those that hit an object
+ // and those that hit the background. The background rays should
+ // be first, so we start and the end and push rays to the beginning
+ // that did not hit anything
+ RayPacketData* data = rays.data;
+ int newBegin = rays.begin();
+ while(!data->hitMatl[newBegin] && newBegin < rays.end())
+ newBegin++;
+ for(int i=rays.end()-1;i>=newBegin;i--){
+ if(!data->hitMatl[i]){
+ // Move hitPrim, hitMatl, hitTex, origin, direction, minT, time
+ swap(data->hitPrim, i, newBegin);
+ swap(data->hitMatl, i, newBegin);
+ swap(data->hitTex, i, newBegin);
+ for(int k=0;k<3;k++)
+ swap(data->origin[k], i, newBegin);
+ for(int k=0;k<3;k++)
+ swap(data->direction[k], i, newBegin);
+ swap(data->minT, i, newBegin);
+ swap(data->time, i, newBegin);
+
+ // Conditionally: normal
+ for(int k=0;k<3;k++)
+ swap(data->normal[k], i, newBegin);
+
+ // Conditionally: ffnormal,
+ for(int k=0;k<3;k++)
+ swap(data->ffnormal[k], i, newBegin);
+
+ // Conditionally: hitPosition,
+ for(int k=0;k<3;k++)
+ swap(data->hitPosition[k], i, newBegin);
+
+ // Conditionally: texCoords, dPdu, dpDv
+ // Perhaps these do not need to be moved???
+ for(int k=0;k<3;k++)
+ swap(data->texCoords[k], i, newBegin);
+ for(int k=0;k<3;k++)
+ swap(data->dPdu[k], i, newBegin);
+ for(int k=0;k<3;k++)
+ swap(data->dPdv[k], i, newBegin);
+
+ // Move sample_id, region_id
+ swap(data->sample_id, i, newBegin);
+ swap(data->region_id, i, newBegin);
+
+ // Move result
+ for(int k=0;k<3;k++)
+ swap(result.colordata[k], i, newBegin);
+
+ // Move total attenuation
+ for(int k=0;k<3;k++)
+ swap(total_attenuation.colordata[k], i, newBegin);
+
+ // Move permute
+ swap(permute.data, i, newBegin);
+ newBegin++;
+ while(!data->hitMatl[newBegin] && newBegin < i)
+ newBegin++;
+ i++;
+ }
+ }
+ rays.resize(newBegin, rays.end());
+}
+
void KajiyaPathtracer::traceRays(const RenderContext& context, RayPacket&
rays)
{
Modified: trunk/Engine/Renderers/KajiyaPathtracer.h
==============================================================================
--- trunk/Engine/Renderers/KajiyaPathtracer.h (original)
+++ trunk/Engine/Renderers/KajiyaPathtracer.h Mon Nov 26 07:40:59 2007
@@ -3,6 +3,7 @@
#define Manta_Engine_KajiyaPathtracer_h
#include <Interface/Renderer.h>
+#include <Interface/Packet.h>
#include <sgi_stl_warnings_off.h>
#include <string>
#include <vector>
@@ -14,6 +15,16 @@
class KajiyaPathtracer : public Renderer {
public:
+ enum PreSortMode {
+ PreSortNone, PreSortDirection, PreSortOrigin, PreSort5D
+ };
+ enum MatlSortMode {
+ MatlSortBackgroundSweep, MatlSortSweep, MatlSortFull
+ };
+ enum RussianRouletteMode {
+ RussianRouletteNone, RussianRouletteFull
+ };
+
KajiyaPathtracer() {}
KajiyaPathtracer(const vector<string>& args);
virtual ~KajiyaPathtracer();
@@ -29,6 +40,31 @@
private:
KajiyaPathtracer(const KajiyaPathtracer&);
KajiyaPathtracer& operator=(const KajiyaPathtracer&);
+
+ std::vector<PreSortMode> presort_mode;
+ std::vector<MatlSortMode> matlsort_mode;
+ std::vector<RussianRouletteMode> russian_roulette_mode;
+ ShadowAlgorithm* ambient_only_sa;
+ int override_maxdepth;
+ bool do_ambient_on_maxdepth;
+
+ void presort_origin(const RenderContext& context, RayPacket& rays,
Packet<Color>& result,
+ Packet<Color>& total_attenuation, Packet<int>&
permute);
+ void presort_direction(const RenderContext& context, RayPacket& rays,
Packet<Color>& result,
+ Packet<Color>& total_attenuation, Packet<int>&
permute);
+ void presort_5d(const RenderContext& context, RayPacket& rays,
Packet<Color>& result,
+ Packet<Color>& total_attenuation, Packet<int>& permute);
+
+ void matlsort_sweep(const RenderContext& context, RayPacket& rays,
Packet<Color>& result,
+ Packet<Color>& total_attenuation, Packet<Color>&
reflectance, Packet<int>& permute);
+ void matlsort_bgsweep(const RenderContext& context, RayPacket& rays,
Packet<Color>& result,
+ Packet<Color>& total_attenuation, Packet<int>&
permute);
+ void matlsort_full(const RenderContext& context, RayPacket& rays,
Packet<Color>& result,
+ Packet<Color>& total_attenuation, Packet<int>&
permute);
+
+ void russian_roulette_full(const RenderContext& context, RayPacket&
rays, Packet<Color>& result,
+ Packet<Color>& total_attenuation,
Packet<Color>& reflectance,
+ Packet<int>& permute);
};
}
- [Manta] r1868 - trunk/Engine/Renderers, sparker, 11/26/2007
Archive powered by MHonArc 2.6.16.