Thursday, 14 February 2013

Scattering

First attempt at scattering. One beam is emitted from the left.
Scattering and absorb coefficient = 0.1
Each beam is "traversed" in a Woodcock tracking style with stepsizes given by
-ln ( 1 - rand()) / (max extinction coefficient)

If (rand() < ext / max ext) we scatter.
"ext" is the extinction coefficient in the given point (heterogene media) and "max ext" is the maximum extinction coefficient available in this media.
This means that in homogene media, scattering occur for each step. In heterogene media, scattering is also dependent on how thick the media is at a given point.
In the image below each beam is allowed to scatter every time, the "break off"-beam has right now a complete random direction. Maximum depth of the "scatter-tree" was 4. Whether scattering is allowed might instead be determined by how much light is left in a beam.
Only one initial beam is emitted.

































Only one initial beam is emitted.
In the image below, each beam may scatter once, with a max depth of 4.:






The code for our scattering can be seen below.


while(s < beam.t)
{
//Woodcock tracking over the scattering coefficients
float r = randomRayGenerator.randNum();
s += -log((1-r))/maxScatter;

if(s > beam.t) break;

//if heterogen we have to get the scatter coefficient at the current point
if (hetero) pointExt = beam.pm->getScatter(beam.origin + s*beam.direction, beam.color);

if(((float)rand()/(float)RAND_MAX) < pointExt/maxScatter )  //does a scattering event occur?
{
beam.allowScatter = false;
scatter++;
//the flux of the scattered beam
Vector3 f = beam.flux * exp(-s*beam.pm->getAbsorb(Vector3(0),                                                                                               beam.color));
Vector3 origin = beam.origin + beam.direction*s;

//new ray from the medias phase function
Ray beamRay = randomRayGenerator.rayInCone(origin, beam.direction, beam.pm->getPhase(beam.color));

Beam tempBeam = Beam(origin, beamRay.d, f, beam.radius, beam.scatterDepth + 1, beam.color);
//Bookkeeping
tempBeam.setParMedia(beam.pm);
if(useKDtree){
tempBeam.maxExt = beam.maxExt;
tempBeam.maxScatter = beam.maxScatter;
tempBeam.hasUsedKDtree = false;
}
if(hetero)
{
tempBeam.numberOfPoints = 0;
}
HitInfo beamHitInfo;
//Trace the new beam and add it to the scattering queue. 
if(trace(beamHitInfo, beamRay)){
int depth = 0;
beamHitInfo.material->traceBeam(tempBeam, beamHitInfo, *this, depth+1);
} else { // beam doesn't hit anything.
Vector3 dest = origin + (beamRay.d*maxDistance); 
tempBeam.setT(maxDistance);
tempBeam.setDestination(dest);
if(hetero)
{
tempBeam.woodCockTracking(*this);
}
if(!useKDtree)addBeam(tempBeam);
}
return; 
}
}

No comments:

Post a Comment