After implementing scattering in the participating media we had some problems when rendering highly scattering materials. Our first implementation used recursion, so with highly scattering materials we had a recursion depth of 100+. This caused a stack overflow in out program, which we solved by keeping a vector of beams we haven't checked for scattering yet, and then just looping trough that vector. The created scatterbeams are then added to the vector instead of recursively scattering.
void
Scene::addBeam(Beam beam) {
beamsToBeAdded.push_back(beam);
}
void
Scene::addBeams(){
int startSize = beamsToBeAdded.size();
//we run through the vector of beams that haven't been checked for scattering yet
while(beamsToBeAdded.size()>0){
Beam beam = (Beam)beamsToBeAdded[0];
beamsToBeAdded.erase(beamsToBeAdded.begin());
//we only scatter if the participating media is inhomogeneous or the scattering value is greater than zero
//There is no reason to add the beams to the tree if the scattering coefficient is zero
if(hetero || beam.pm->getScatter(Vector3(0), beam.color) != 0){
if(beam.scatterDepth < maxScatterDepth) scatterBeam(beam);
//either subdivide the beam or add the current beam to the bvh.
if(useSubdivide){
subdivideBeam(beam);
}else{
beamvector.push_back(beam);
}
}
}
}
Another problem we encountered related to scattering was when combining scattering with the kd-tree for inhomogeneous participating media. When splitting the beams according to the kd-tree we had to make sure that only onescattering event occured across all the created split beams. This required some additional book keeping where each splitbeam knows the previous one, and can ask that beam if it's allowed to scatter.
No comments:
Post a Comment