Fix T47411: Cycles portals luminance artifacts

When using multiple portals, scene areas behind one of the portals were rendered darker than they should.
The reason for that is a pretty stupid mistake: Since portals are only used at positions that aren't behind them,
only portals that are used should be accounted for in the PDF calculation. That was actually the case, but the final
divide incorrectly divided by the total amount of portals, not the amount of visible ones.

Another issue with areas behind portals was the PDF evaluation function.
The new evaluation code is shorter, simpler and fixes this issue.

Also, the threshold for the distance check was increased to avoid artifacts where portals touch a surface.
This commit is contained in:
Lukas Stockner 2016-02-17 00:29:21 +01:00
parent 0ccae52394
commit 8d95178c0b
Notes: blender-bot 2023-09-08 04:55:43 +02:00
Referenced by issue #47411, Cycles portals: Luminance artifacts
1 changed files with 25 additions and 28 deletions

View File

@ -262,7 +262,7 @@ ccl_device_inline bool background_portal_data_fetch_and_check_side(KernelGlobals
*dir = make_float3(data3.y, data3.z, data3.w);
/* Check whether portal is on the right side. */
if(dot(*dir, P - *lightpos) > 1e-5f)
if(dot(*dir, P - *lightpos) > 1e-4f)
return true;
return false;
@ -276,6 +276,7 @@ ccl_device float background_portal_pdf(KernelGlobals *kg,
{
float portal_pdf = 0.0f;
int num_possible = 0;
for(int p = 0; p < kernel_data.integrator.num_portals; p++) {
if(p == ignore_portal)
continue;
@ -284,13 +285,14 @@ ccl_device float background_portal_pdf(KernelGlobals *kg,
if(!background_portal_data_fetch_and_check_side(kg, P, p, &lightpos, &dir))
continue;
/* There's a portal that could be sampled from this position. */
if(is_possible) {
/* There's a portal that could be sampled from this position. */
*is_possible = true;
}
num_possible++;
float t = -(dot(P, dir) - dot(lightpos, dir)) / dot(direction, dir);
if(t <= 1e-5f) {
if(t <= 1e-4f) {
/* Either behind the portal or too close. */
continue;
}
@ -312,7 +314,12 @@ ccl_device float background_portal_pdf(KernelGlobals *kg,
portal_pdf += area_light_sample(P, &lightpos, axisu, axisv, 0.0f, 0.0f, false);
}
return kernel_data.integrator.num_portals? portal_pdf / kernel_data.integrator.num_portals: 0.0f;
if(ignore_portal >= 0) {
/* We have skipped a portal that could be sampled as well. */
num_possible++;
}
return (num_possible > 0)? portal_pdf / num_possible: 0.0f;
}
ccl_device int background_num_possible_portals(KernelGlobals *kg, float3 P)
@ -431,38 +438,28 @@ ccl_device float background_light_pdf(KernelGlobals *kg, float3 P, float3 direct
/* Probability of sampling portals instead of the map. */
float portal_sampling_pdf = kernel_data.integrator.portal_pdf;
float portal_pdf = 0.0f, map_pdf = 0.0f;
if(portal_sampling_pdf > 0.0f) {
/* Evaluate PDF of sampling this direction by portal sampling. */
bool is_possible = false;
float portal_pdf = background_portal_pdf(kg, P, direction, -1, &is_possible);
if(portal_pdf == 0.0f) {
portal_pdf = background_portal_pdf(kg, P, direction, -1, &is_possible) * portal_sampling_pdf;
if(!is_possible) {
/* Portal sampling is not possible here because all portals point to the wrong side.
* If map sampling is possible, it would be used instead, otherwise fallback sampling is used. */
if(portal_sampling_pdf == 1.0f) {
/* If there are no possible portals at this point,
* the fallback sampling would have been used.
* Otherwise, the direction would not be sampled at all => pdf = 0
*/
return is_possible? 0.0f: kernel_data.integrator.pdf_lights / M_4PI_F;
return kernel_data.integrator.pdf_lights / M_4PI_F;
}
else {
/* We can only sample the map. */
return background_map_pdf(kg, direction) * kernel_data.integrator.pdf_lights;
}
} else {
if(portal_sampling_pdf == 1.0f) {
/* We can only sample portals. */
return portal_pdf * kernel_data.integrator.pdf_lights;
}
else {
/* We can sample both, so combine with MIS. */
return (background_map_pdf(kg, direction) * (1.0f - portal_sampling_pdf)
+ portal_pdf * portal_sampling_pdf) * kernel_data.integrator.pdf_lights;
/* Force map sampling. */
portal_sampling_pdf = 0.0f;
}
}
}
/* No portals in the scene, so must sample the map.
* At least one of them is always possible if we have a LIGHT_BACKGROUND.
*/
return background_map_pdf(kg, direction) * kernel_data.integrator.pdf_lights;
if(portal_sampling_pdf < 1.0f) {
/* Evaluate PDF of sampling this direction by map sampling. */
map_pdf = background_map_pdf(kg, direction) * (1.0f - portal_sampling_pdf);
}
return (portal_pdf + map_pdf) * kernel_data.integrator.pdf_lights;
}
#endif