2
$\begingroup$

I'm trying to implement the multiple importance sampling path tracing, the MIS path tracing uses the MIS to combine the direct light sampling and brdf sampling to evaluate the direct lighting.

The direct lighting estimator part (the intersection point on the object is pos):

  1. sample a point P on the light plane and get the light intensity Li
  2. get dir = P - pos, wi = normalize(dir), dist2 = dot(dir, dir), light_pdf = 1 / area / light_cnt
  3. get the light_pdf wrt solid angle ==> light_pdf_sa = light_pdf * dist2 / dot(light_normal, -wi)
  4. get the brdf_pdf wrt to wi, wo(the incident direction) and surface intersection info rec
  5. calculate the direct lighting part = eval(wi, wo, rec) * Li * dot(wi, n) / light_pdf_sa * powerhueristic(1., light_pdf_sa, 1., brdf_pdf)

The brdf estimator part:

  1. sample an out direction wi wrt the wo and the material info
  2. shoot the shadow ray from pos with the direction wi and intersect with the scene
  3. if the shadow ray hit a light, then get the light color Li, light_pdf = 1/area/light_cnt, and the light_normal, dist2 (the square of the hit point and the surface point) go to 4
  4. get the light_pdf wrt solid angle ==> light_pdf_sa = light_pdf * dist2 / dot(light_normal, -wi)
  5. get the brdf_pdf wrt to wi, wo(the incident direction) and surface intersection info rec
  6. calculate the brdf part = eval(wi, wo, rec) * Li * dot(wi, n) / brdf_pdf * powerhueristic(1., brdf_pdf, 1., light_pdf_sa)

Finally, add the direct lighting part and the brdf part together

Here is the MIS direct lighting code:

bool direct_lighting_MIS(out vec3 wi, out vec3 weight, out vec3 L, const in vec3 wo, const in record rec){
    vec3 n = rec.out_normal;
    vec3 pt_on_obj = rec.pos;
    vec3 pt_on_lit;
    vec3 lit_normal;
    float lit_pdf;
    vec3 Li;
    sample_from_light(pt_on_lit, lit_normal, lit_pdf, Li);
    vec3 dir = pt_on_lit - pt_on_obj;
    float dist = length(dir);
    wi = normalize(dir);
    L = vec3(0);
    if(is_visible(pt_on_obj, dir, n) && lit_pdf > 0.){
        float brdf_pdf = get_pdf(wi, wo, rec);
        float lit_pdf_sa = lit_pdf * dist * dist / dot(lit_normal, -wi);
        L += eval(wi, wo, rec) * Li * dot(n, wi) / lit_pdf_sa * 
             PowerHeuristic(1., lit_pdf_sa, 1., brdf_pdf);
    }
    
    if(sample_brdf(wi, weight, wo, rec)){
        float brdf_pdf = get_pdf(wi, wo, rec);
        ray r_t = ray(rec.pos, wi);
        record rec_t;
        bool valid;
        hit(r_t, rec_t, valid);
        float dist = length(at(r_t, rec_t.t) - r_t.A);
        if(valid){
            for(int i = 0; i < light_cnts; i ++){
                if(rec_t.obj_id == lights[i] && !rec_t.is_back_face){
                    lit_pdf = light_pdf(lights[i]);
                    Li = light_intensity(rec_t.mat_id);
                    float lit_pdf_sa = lit_pdf * dist * dist / dot(rec_t.normal, -wi);
                    //float brdf_pdf_area = brdf_pdf * dot(rec_t.normal, -wi) / (dist * dist);
                    L += eval(wi, wo, rec) * Li * dot(n, wi) / brdf_pdf *
                         PowerHeuristic(1., brdf_pdf, 1., lit_pdf_sa);
                }
            }
        }
        return true;
    }
    return false;
}

Comparision between the image produced by MIS and the brute force image

Here are the results:

MIS:

MIS

link

Brute force

enter image description here

link

the difference

enter image description here

Edit 2022/10/5:

After disabling ANGLE in chrome and launching chrome in OpenGL mode, the brightness of MIS and brute force appears to be the same (I don't know why and it's ridiculous...)

$\endgroup$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.