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;
    }

}