[Bf-blender-cvs] [457eadf] compositor-2016: Cycles: Use faster ray-quad-intersection test

Lukas Stockner noreply at git.blender.org
Wed Jun 8 21:53:25 CEST 2016


Commit: 457eadf812e609862dd4afedc6a79c5b192e6b79
Author: Lukas Stockner
Date:   Mon Jun 6 23:38:28 2016 +0200
Branches: compositor-2016
https://developer.blender.org/rB457eadf812e609862dd4afedc6a79c5b192e6b79

Cycles: Use faster ray-quad-intersection test

The original quad intersection test works by just testing against the two triangles that define the quad.
However, in this case it's actually faster to use the same test that's also used for portals: Determining
the distance to the plane in which the quad lies, calculating the hitpoint and checking whether it's in the
quad by projecting onto the sides.

Reviewers: brecht, sergey, dingto

Reviewed By: dingto

Differential Revision: https://developer.blender.org/D2045

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

M	intern/cycles/kernel/kernel_light.h
M	intern/cycles/util/util_math.h

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

diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 675eacf..736a884 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -291,24 +291,13 @@ ccl_device float background_portal_pdf(KernelGlobals *kg,
 		}
 		num_possible++;
 
-		float t = -(dot(P, dir) - dot(lightpos, dir)) / dot(direction, dir);
-		if(t <= 1e-4f) {
-			/* Either behind the portal or too close. */
-			continue;
-		}
-
 		float4 data1 = kernel_tex_fetch(__light_data, (p + kernel_data.integrator.portal_offset)*LIGHT_SIZE + 1);
 		float4 data2 = kernel_tex_fetch(__light_data, (p + kernel_data.integrator.portal_offset)*LIGHT_SIZE + 2);
 
 		float3 axisu = make_float3(data1.y, data1.z, data1.w);
 		float3 axisv = make_float3(data2.y, data2.z, data2.w);
 
-		float3 hit = P + t*direction;
-		float3 inplane = hit - lightpos;
-		/* Skip if the the ray doesn't pass through portal. */
-		if(fabsf(dot(inplane, axisu) / dot(axisu, axisu)) > 0.5f)
-			continue;
-		if(fabsf(dot(inplane, axisv) / dot(axisv, axisv)) > 0.5f)
+		if(!ray_quad_intersect(P, direction, 1e-4f, FLT_MAX, lightpos, axisu, axisv, dir, NULL, NULL))
 			continue;
 
 		portal_pdf += area_light_sample(P, &lightpos, axisu, axisv, 0.0f, 0.0f, false);
@@ -729,8 +718,8 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D,
 
 		float3 light_P = make_float3(data0.y, data0.z, data0.w);
 
-		if(!ray_quad_intersect(P, D, t,
-		                       light_P, axisu, axisv, &ls->P, &ls->t))
+		if(!ray_quad_intersect(P, D, 0.0f, t,
+		                       light_P, axisu, axisv, Ng, &ls->P, &ls->t))
 		{
 			return false;
 		}
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 32924f9..53944ec 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -1479,21 +1479,25 @@ ccl_device bool ray_triangle_intersect_uv(
 	return true;
 }
 
-ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_t,
-                                   float3 quad_P, float3 quad_u, float3 quad_v,
+ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_mint, float ray_maxt,
+                                   float3 quad_P, float3 quad_u, float3 quad_v, float3 quad_n,
                                    float3 *isect_P, float *isect_t)
 {
-	float3 v0 = quad_P - quad_u*0.5f - quad_v*0.5f;
-	float3 v1 = quad_P + quad_u*0.5f - quad_v*0.5f;
-	float3 v2 = quad_P + quad_u*0.5f + quad_v*0.5f;
-	float3 v3 = quad_P - quad_u*0.5f + quad_v*0.5f;
+	float t = -(dot(ray_P, quad_n) - dot(quad_P, quad_n)) / dot(ray_D, quad_n);
+	if(t < ray_mint || t > ray_maxt)
+		return false;
 
-	if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v1, v2, isect_P, isect_t))
-		return true;
-	else if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v2, v3, isect_P, isect_t))
-		return true;
-	
-	return false;
+	float3 hit = ray_P + t*ray_D;
+	float3 inplane = hit - quad_P;
+	if(fabsf(dot(inplane, quad_u) / dot(quad_u, quad_u)) > 0.5f)
+		return false;
+	if(fabsf(dot(inplane, quad_v) / dot(quad_v, quad_v)) > 0.5f)
+		return false;
+
+	if(isect_P) *isect_P = hit;
+	if(isect_t) *isect_t = t;
+
+	return true;
 }
 
 /* projections */




More information about the Bf-blender-cvs mailing list