The light contribution from a photon beam can be described by the following formula:
In our implementation we have implemented the basic idea in the following code segment:
for(int i = 0; i < beamHits.size(); i++)
{
BeamHitInfo bhi = ((BeamHitInfo)(beamHits)[i]);
//make sure the beams doesn't cross the object boundaries
if(ray.pm == bhi.beam.pm){
//not quite sure if this is the correct way to make the blur kernel?
float kr = (1/(2*PI * bhi.beam.radius));
Vector3 flux = (bhi.beam.flux/amountOfBeams);
//only use the color of the beam
if(useColors){
//multiply with 3 because each beam gets a third of its flux removed
flux *= 3;
if(bhi.beam.color == 0) flux *= Vector3(1,0,0);
if(bhi.beam.color == 1) flux *= Vector3(0,1,0);
if(bhi.beam.color == 2) flux *= Vector3(0,0,1);
}
int rayPoints = ray.getPointsUntilT(bhi.rayT);
float extMax = bhi.beam.pm->getExtinctionMax(bhi.beam.color);
float extMaxBeam = bhi.beam.pm->getExtinctionMax(bhi.beam.color);
float scatterMaxBeam = bhi.beam.pm->getScatter(bhi.P, bhi.beam.color);
if(useKDtree){
extMaxBeam = bhi.beam.maxExt;
}
//the flux reduction from the ray passing through the media
float trRay = exp((float)-rayPoints * extMax);
//the flux reduction from the beam passing through the media
float trBeam = exp((float)-(bhi.beam.getPointsUntilT(bhi.beamT)) * extMaxBeam);
//using the phase function to determine the probability that the light is scattered towards the ray direction
float angle = acos(dot(-ray.d, bhi.beam.direction));
float phase = bhi.beam.pm->getPhaseProbability(bhi.beam.color, angle);
float sinRayBeam = sin(acos(dot(-ray.d, bhi.beam.direction)));
//from the progressive photon beams paper
//lm = kr(u) * scatter(xw) * flux * Tr(ray) * Tr(beam) * (phase function(ray dot beam) / sin(ray, beam))
Vector3 color = kr * scatterMaxBeam * flux * trRay * trBeam * (phase / sinRayBeam) ;
shade += color;
}
}
In our implementation we have implemented the basic idea in the following code segment:
for(int i = 0; i < beamHits.size(); i++)
{
BeamHitInfo bhi = ((BeamHitInfo)(beamHits)[i]);
//make sure the beams doesn't cross the object boundaries
if(ray.pm == bhi.beam.pm){
//not quite sure if this is the correct way to make the blur kernel?
float kr = (1/(2*PI * bhi.beam.radius));
Vector3 flux = (bhi.beam.flux/amountOfBeams);
//only use the color of the beam
if(useColors){
//multiply with 3 because each beam gets a third of its flux removed
flux *= 3;
if(bhi.beam.color == 0) flux *= Vector3(1,0,0);
if(bhi.beam.color == 1) flux *= Vector3(0,1,0);
if(bhi.beam.color == 2) flux *= Vector3(0,0,1);
}
int rayPoints = ray.getPointsUntilT(bhi.rayT);
float extMax = bhi.beam.pm->getExtinctionMax(bhi.beam.color);
float extMaxBeam = bhi.beam.pm->getExtinctionMax(bhi.beam.color);
float scatterMaxBeam = bhi.beam.pm->getScatter(bhi.P, bhi.beam.color);
if(useKDtree){
extMaxBeam = bhi.beam.maxExt;
}
//the flux reduction from the ray passing through the media
float trRay = exp((float)-rayPoints * extMax);
//the flux reduction from the beam passing through the media
float trBeam = exp((float)-(bhi.beam.getPointsUntilT(bhi.beamT)) * extMaxBeam);
//using the phase function to determine the probability that the light is scattered towards the ray direction
float angle = acos(dot(-ray.d, bhi.beam.direction));
float phase = bhi.beam.pm->getPhaseProbability(bhi.beam.color, angle);
float sinRayBeam = sin(acos(dot(-ray.d, bhi.beam.direction)));
//from the progressive photon beams paper
//lm = kr(u) * scatter(xw) * flux * Tr(ray) * Tr(beam) * (phase function(ray dot beam) / sin(ray, beam))
Vector3 color = kr * scatterMaxBeam * flux * trRay * trBeam * (phase / sinRayBeam) ;
shade += color;
}
}