So I recently implemented Multiple Importance Sampling in my path tracer which was based on next event estimation. The simple code looks like this
//Direct Light Sampling
int j = sampleLights(hit_info, &geometry_term, &light_pdf, &w_i); //j is the index in light array
if(j == -1)
return light_sample; // black since no ray hits any light source
Ray shadow_ray = {hit_info.hit_point + w_i * RAYBUMP_EPSILON, w_i, INFINITY, true};
HitInfo shadow_hitinfo;
if(!traceRay(&shadow_ray, &shadow_hitinfo) )
{
//traceRay returns false which means light source is visible
mis_weight = light_pdf;
brdf_pdf = max(dot(w_i, hit_info.normal), 0.0f) * INV_PI; //cosine weighted
powerHeuristic(&mis_weight, light_pdf, brdf_pdf, 2);
light_sample = evaluateBRDF(w_i, -ray.dir, hit_info) * light_sources[j].emissive_col * geometry_term;
light_sample *= mis_weight/light_pdf;
}
// BRDF Sampling
Ray brdf_sample_ray;
sampleHemisphere(&brdf_sample_ray, hit_info);
if(traceRay(&brdf_sample_ray, &new_hitinfo) && new_hitinfo.lightID < 0)
return light_sample; //if Light ID < 0, no lights were hit
light_pdf = getLightPdf(new_hitinfo.lightID);
brdf_pdf = max(dot(w_i, hit_info.normal), 0.0f) * INV_PI;
mis_weight = brdf_pdf;
powerHeuristic(&mis_weight, light_pdf, brdf_pdf, 2);
brdf_sample = evaluateBRDF(w_i, -ray.dir, hit_info) * light_sources[j].emissive_col * geometry_term;
brdf_sample *= mis_weight / brdf_pdf;
The problem is without MIS I get images like,
[![enter image description here][1]][1]
This is obtained by setting
`light_sample *= 1/light_pdf; // Note no mis_weight`
and just returning this sample alone. No BRDF sampling.
Where as with MIS as defined above I get darker images like,
[![][2]][2]
The reason is surely the `mis_weight` factor. From what I gathered over the internet my MIS code is ok but theoretically it doesn't seem right. For example suppose we performed Light Sampling first and obtained a `mis_weight`. After that when we tried BRDF sampling, the ray didn't intersect any light source resulting in `light_pdf = 0`. We neglected this estimate. Since we neglected this estimate isn't it wrong to weight our light sample by `mis_weight` when we didn't even use multiple estimators, plus how is the sum of weights equal to 1 when we didnt even estimate anything using the BRDF pdf?
Imo, `mis_weight` factor in `light_sample` should only be used when BRDF sampling also results in a light ray that intersects the light source.
Can anybody explain if these results are ok or there is something wrong with the code?
EDIT:- There is another case which is a little confusing. I am currently using a heuristic (basically power/distance) to choose 1 light out of multiple lights. What if Light sampling and BRDF sampling choose different light sources. Is MIS still valid then? Since the PDF would change resulting the weights not being able to sum to 1 anymore.
[1]: https://i.sstatic.net/7SL0B.png
[2]: https://i.sstatic.net/QYyJw.png