[Bf-blender-cvs] [8d95178] master: Fix T47411: Cycles portals luminance artifacts

Lukas Stockner noreply at git.blender.org
Wed Feb 17 03:08:01 CET 2016


Commit: 8d95178c0bef5f3bd0e3425ca2b45d5474e5f70a
Author: Lukas Stockner
Date:   Wed Feb 17 00:29:21 2016 +0100
Branches: master
https://developer.blender.org/rB8d95178c0bef5f3bd0e3425ca2b45d5474e5f70a

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.

===================================================================

M	intern/cycles/kernel/kernel_light.h

===================================================================

diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 7e09ca3..f8cd361 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -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




More information about the Bf-blender-cvs mailing list