I am writing my first path tracer and kind of feeling confused by some mechanisms. For example, when I trace a ray and the ray hits a area emitter, then how to determine the radiance of this direct hit? I know that in rendering equation, we have:
$L_o(w_o, x) = L_e(w_o, x) + \int f_r(w_i, w_o, x)\cos \theta dw_i$
and here I should determine what $L_e(w_o, x)$ is. My question is, for $L_e(w_o, x)$ here, should it incorporate distance attenuation (e.g. for area light, pow(distance, 2)) and $\cos$ term? Because I've noticed that if I scale down the emission_part
of when calculating the following code:
color = (direct_part + emission_part) * throughput
The rendering actually converges several times faster (though I think it will lead to biased results), and the there is less aliasing effect around the emitter. Also, I tried to understand how other renderers cope with this situation (like mitsuba2, path.cpp
):
result[active] += emission_weight * throughput * emitter->eval(si, active);
I don't see how emitter->eval(si, active)
above leveraging si
(surface interaction vertex), like calculating distance attenuation to the sampled intensity, mitsuba2
just uses Texture::eval(...)
to calculate the emitted radiance. Therefore, I think this is the reason for its rendering result to have no saw-tooth aliasing anywhere but places around the emitter (see the figure below: cornell box scene with area emitter):
So, should I just use the formulation below, just like evaluating direct illumination
ret_int = emitter.intensity * distance_attenuate(ray_length) * cosine_term
Or simply returns its original intensity:
ret_int = emitter.intensity
When dealing with ray hitting an emitter?