glm::vec3 DirectLightingIntegrator::LightPDFEnergy(const Intersection &light_sample_isx, const Intersection &isx, const Ray &light_sample, const glm::vec3 &woW, unsigned int n_light, unsigned int n_brdf) { glm::vec3 ray_color(0, 0, 0); Material* M = isx.object_hit->material; //material of point hit Geometry* L = light_sample_isx.object_hit; //light source float lightPDF = L->RayPDF(light_sample_isx, light_sample); //if light pdf is less than zero, return no light if (lightPDF <= 0.0f) { return glm::vec3(0); } //get BRDFPDF and energy from the material float brdfPDF; float dummy; glm::vec3 M_energy(M->EvaluateScatteredEnergy(isx, woW, light_sample.direction, brdfPDF)); //terminate early if brdf pdf is zero; if (brdfPDF <= 0.0f) return ray_color; glm::vec3 L_energy(L->material->EvaluateScatteredEnergy(light_sample_isx, woW, -light_sample.direction, dummy)); float W = MIS(lightPDF, brdfPDF); //MIS power heuristic weighing function ray_color = ComponentMult(L_energy, M_energy); // multiply the energy of the light with BRDF reflected energy ray_color = ComponentMult(ComponentMult(ray_color, M->base_color), isx.texture_color); ray_color = ray_color*W/lightPDF*glm::abs(glm::dot(isx.normal, light_sample.direction)); // and then do the solid angle PDF and the cosine return ray_color; }
glm::vec3 Integrator::CalculateEnergy(const Intersection &light_sample_isx, const Intersection &isx, const Ray &light_sample, const glm::vec3 &woW) { glm::vec3 ray_color(0, 0, 0); Material* M = isx.object_hit->material; //material of point hit Geometry* L = light_sample_isx.object_hit; //light source float dummy; //Intersection isx_light = L->GetIntersection(light_sample); ray_color = ComponentMult(L->material->EvaluateScatteredEnergy(light_sample_isx, woW, -light_sample.direction, dummy), M->EvaluateScatteredEnergy(isx, woW, light_sample.direction, dummy)); // multiply the energy of the light with BRDF reflected energy ray_color = ray_color/L->RayPDF(light_sample_isx, light_sample)*glm::abs(glm::dot(isx.normal, light_sample.direction)); // and then do the solid angle PDF and the cosine ray_color = glm::clamp(ray_color, 0.0f, 1.0f); return ray_color; }
glm::vec3 DirectLightingIntegrator::BxDFPDFEnergy(const Intersection &isx, const glm::vec3 &woW, unsigned int n_light, unsigned int n_brdf) { glm::vec3 ray_color(0, 0, 0); glm::vec3 wiW(0, 0, 0);//this will be obtained by sampling BxDf Material* M = isx.object_hit->material; //material of point hit float brdfPDF; float lightPDF; float dummy; float rand1 = unif_distribution(mersenne_generator); float rand2 = unif_distribution(mersenne_generator); glm::vec3 M_energy(M->SampleAndEvaluateScatteredEnergy(isx, woW, wiW, brdfPDF, rand1, rand2)); //use sampled wiW to check if I can hit the light Ray shadow_feeler(isx.point, wiW); Intersection light_isx = intersection_engine->GetIntersection(shadow_feeler); Geometry* L; //this holds the intersected light source //terminate early if brdf pdf is zero; if (brdfPDF <= 0.0f) return ray_color; if (light_isx.object_hit == NULL)//if ray didnt hit anything return ray_color; if (light_isx.object_hit->material->is_light_source) { L = light_isx.object_hit; lightPDF = L->RayPDF(light_isx, shadow_feeler); if (lightPDF <= 0) { return ray_color; } glm::vec3 L_energy(L->material->EvaluateScatteredEnergy(light_isx, woW, -shadow_feeler.direction, dummy)); float W = MIS(brdfPDF, lightPDF); ray_color = ComponentMult(L_energy, M_energy); ray_color = ComponentMult(ComponentMult(ray_color, M->base_color), isx.texture_color); ray_color = ray_color*W/brdfPDF*glm::abs(glm::dot(isx.normal, shadow_feeler.direction)); return ray_color; } else { return ray_color; } }