#include "dest.h" #include "phong.h" #include "scene.h" #include "Common.h" #include "SamplingStrategy.h" double PhysicalBRDFSamplingStrategy::BounceRay(RAY &rin,HITREC &hin,RAY &rout,HITREC &hout) { DENSITY_ESTIMATION_DATA_PTR thisData; BSDF *thisBsdf; PHONG_BRDF *phong; COORDSYS reflCoord; VECTOR reflDir; COLOR tmp; double probDiffuse,probNonDiffuse,probTot; double xi_1,xi_2,pdf1,pdf2; float tmpCos; int ns; // Access density estimation data more easily thisData = (DENSITY_ESTIMATION_DATA_PTR) hin.patch->radiance_data; thisBsdf = hin.patch->surface->material->bsdf; // Halton sampling xi_1 = drand48(); xi_2 = drand48(); // Determine probabilities... tmp = BsdfReflectance(thisBsdf, /*&(hin.patch->midpoint)*/ NULL, NULL/*TODO*/, DIFFUSE_COMPONENT); probDiffuse = COLORSUMABSCOMPONENTS(tmp); tmp = BsdfReflectance(thisBsdf, /*&(hin.patch->midpoint),*/ NULL, NULL /*TODO*/, ALL_COMPONENTS & (~DIFFUSE_COMPONENT)); probNonDiffuse = COLORSUMABSCOMPONENTS(tmp); probTot = probDiffuse + probNonDiffuse; // Initiate cos theta n sampling phong = (PHONG_BRDF *) thisBsdf->data; ns = (int)phong->Ns; reflDir = IdealReflectedDirection(&rin.dir,&hin.normal); VectorCoordSys(&reflDir,&reflCoord); if (drand48()*probTot <= probDiffuse) { // Diffuse particle... // Initiate reflection ray rout.pos = hin.point; rout.dir = SampleHemisphereCosTheta(&(thisData->coordsys),xi_1,xi_2,&pdf1); tmpCos = VECTORDOTPRODUCT(reflDir,rout.dir); pdf2 = ( (ns + 1.0) * pow(tmpCos,ns) * M_1_2PI ); } else { // Specular particle... // Initiate reflection ray rout.pos = hin.point; rout.dir = SampleHemisphereCosNTheta(&reflCoord,(int)phong->Ns,xi_1,xi_2,&pdf2); // Check we are on the good side tmpCos = VECTORDOTPRODUCT(rout.dir,hin.normal); if (tmpCos<0.0) return 0.0; pdf1 = tmpCos * M_1_PI; } // Send ray RayCastingFunction(hin.patch,&rout,hout); // SetProbability return (pdf1*probDiffuse + pdf2*probNonDiffuse) / probTot; } double PhysicalBRDFSamplingStrategy::EvalRay(RAY &rin,HITREC &hin,RAY &rout,HITREC &,const double cosTheta) { BSDF *thisBsdf; PHONG_BRDF *phong; VECTOR reflDir; COLOR tmp; double probDiffuse,probNonDiffuse,probTot; double tmpCos,pdf1,pdf2; int ns; // Sample BRDF only. if (cosTheta<0.0) return 0.0; // Easy access thisBsdf = hin.patch->surface->material->bsdf; phong = (PHONG_BRDF *) thisBsdf->data; ns = (int)phong->Ns; // Determine probabilities... tmp = BsdfReflectance(thisBsdf, /*&(hin.patch->midpoint)*/ NULL, NULL /*TODO*/, DIFFUSE_COMPONENT); probDiffuse = COLORSUMABSCOMPONENTS(tmp); tmp = BsdfReflectance(thisBsdf, /*&(hin.patch->midpoint),*/ NULL, NULL /*TODO*/,d ALL_COMPONENTS & (~DIFFUSE_COMPONENT)); probNonDiffuse = COLORSUMABSCOMPONENTS(tmp); probTot = probDiffuse + probNonDiffuse; // Probability diffuse pdf1 = cosTheta * M_1_PI; // Probability specular reflDir = IdealReflectedDirection(&rin.dir,&hin.normal); tmpCos = VECTORDOTPRODUCT(reflDir,rout.dir); pdf2 = ( (ns + 1.0) * pow(tmpCos,ns) * M_1_2PI ); // SetProbability return (pdf1*probDiffuse + pdf2*probNonDiffuse) / probTot; }