[Bf-blender-cvs] [4d0f9d07ebf] cycles_texture_cache: Cycles: Added dNdu to kernel globals on CPU, using it for more accurate ray differentials in specular and glossy reflection

Stefan Werner noreply at git.blender.org
Mon Nov 27 20:40:21 CET 2017


Commit: 4d0f9d07ebfbe041c8a53870a61d4264486b9abd
Author: Stefan Werner
Date:   Wed May 10 15:09:47 2017 +0200
Branches: cycles_texture_cache
https://developer.blender.org/rB4d0f9d07ebfbe041c8a53870a61d4264486b9abd

Cycles: Added dNdu to kernel globals on CPU, using it for more accurate ray differentials in specular and glossy reflection

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

M	intern/cycles/kernel/closure/bsdf.h
M	intern/cycles/kernel/closure/bsdf_microfacet.h
M	intern/cycles/kernel/closure/bsdf_reflection.h
M	intern/cycles/kernel/geom/geom_curve_intersect.h
M	intern/cycles/kernel/geom/geom_motion_triangle_shader.h
M	intern/cycles/kernel/geom/geom_triangle.h
M	intern/cycles/kernel/kernel_shader.h
M	intern/cycles/kernel/kernel_types.h

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

diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index e4573024e85..7a9f8d02670 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -91,7 +91,7 @@ ccl_device_forceinline int bsdf_sample(KernelGlobals *kg,
 			break;
 		case CLOSURE_BSDF_REFLECTION_ID:
 			label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-				eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+				eval, omega_in, &domega_in->dx, &domega_in->dy, pdf, sd);
 			break;
 		case CLOSURE_BSDF_REFRACTION_ID:
 			label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
@@ -108,7 +108,7 @@ ccl_device_forceinline int bsdf_sample(KernelGlobals *kg,
 		case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
 		case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
 			label = bsdf_microfacet_ggx_sample(kg, sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-				eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+				eval, omega_in, &domega_in->dx, &domega_in->dy, pdf, sd);
 			break;
 		case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
 		case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
@@ -124,7 +124,7 @@ ccl_device_forceinline int bsdf_sample(KernelGlobals *kg,
 		case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
 		case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
 			label = bsdf_microfacet_beckmann_sample(kg, sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
-				eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+				eval, omega_in, &domega_in->dx, &domega_in->dy, pdf, sd);
 			break;
 		case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
 		case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index b661629dafd..3cd60a76cde 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -552,7 +552,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, con
 	return make_float3(out, out, out);
 }
 
-ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf, const ShaderData *sd)
 {
 	const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
 	float alpha_x = bsdf->alpha_x;
@@ -681,10 +681,22 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
 					}
 
 #ifdef __RAY_DIFFERENTIALS__
+#ifdef __DNDU__
+					float3 dndx = sd->dNdu * sd->du.dx + sd->dNdv * sd->dv.dx;
+					float3 dndy = sd->dNdu * sd->du.dy + sd->dNdv * sd->dv.dy;
+					float3 dwodx = -dIdx;
+					float3 dwody = -dIdy;
+					float dDNdx = dot(dwodx, N) + dot(I, dndx);
+					float dDNdy = dot(dwody, N) + dot(I, dndy);
+					*domega_in_dx = dwodx + 2.f * (dot(I, N) * dndx + dDNdx * N);
+					*domega_in_dy = dwody + 2.f * (dot(I, N) * dndy + dDNdy * N);
+#else
 					*domega_in_dx = (2.0f * dot(m, dIdx)) * m - dIdx;
 					*domega_in_dy = (2.0f * dot(m, dIdy)) * m - dIdy;
-					*domega_in_dx *= 10.0f;
-					*domega_in_dy *= 10.0f;
+#endif
+					const float softness = min(alpha_x, alpha_y) * 10.0f;
+					*domega_in_dx *= (1.0f + softness);
+					*domega_in_dy *= (1.0f + softness);
 #endif
 				}
 			}
@@ -957,7 +969,7 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderClosure *sc
 	return make_float3(out, out, out);
 }
 
-ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals *kg, const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals *kg, const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf, const ShaderData *sd)
 {
 	const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
 	float alpha_x = bsdf->alpha_x;
@@ -1049,10 +1061,22 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals *kg, const ShaderCl
 					}
 
 #ifdef __RAY_DIFFERENTIALS__
-					*domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
-					*domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
-					*domega_in_dx *= 10;
-					*domega_in_dy *= 10;
+#ifdef __DNDU__
+					float3 dndx = sd->dNdu * sd->du.dx + sd->dNdv * sd->dv.dx;
+					float3 dndy = sd->dNdu * sd->du.dy + sd->dNdv * sd->dv.dy;
+					float3 dwodx = -dIdx;
+					float3 dwody = -dIdy;
+					float dDNdx = dot(dwodx, N) + dot(I, dndx);
+					float dDNdy = dot(dwody, N) + dot(I, dndy);
+					*domega_in_dx = dwodx + 2.f * (dot(I, N) * dndx + dDNdx * N);
+					*domega_in_dy = dwody + 2.f * (dot(I, N) * dndy + dDNdy * N);
+#else
+					*domega_in_dx = (2.0f * dot(m, dIdx)) * m - dIdx;
+					*domega_in_dy = (2.0f * dot(m, dIdy)) * m - dIdy;
+#endif
+					const float softness = min(alpha_x, alpha_y) * 10.0f;
+					*domega_in_dx *= (1.0f + softness);
+					*domega_in_dy *= (1.0f + softness);
 #endif
 				}
 			}
diff --git a/intern/cycles/kernel/closure/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h
index 1d21614ecee..ffccb3695f6 100644
--- a/intern/cycles/kernel/closure/bsdf_reflection.h
+++ b/intern/cycles/kernel/closure/bsdf_reflection.h
@@ -53,7 +53,7 @@ ccl_device float3 bsdf_reflection_eval_transmit(const ShaderClosure *sc, const f
 	return make_float3(0.0f, 0.0f, 0.0f);
 }
 
-ccl_device int bsdf_reflection_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_reflection_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf, const ShaderData *sd)
 {
 	const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
 	float3 N = bsdf->N;
@@ -64,8 +64,20 @@ ccl_device int bsdf_reflection_sample(const ShaderClosure *sc, float3 Ng, float3
 		*omega_in = (2 * cosNO) * N - I;
 		if(dot(Ng, *omega_in) > 0) {
 #ifdef __RAY_DIFFERENTIALS__
-			*domega_in_dx = 2 * dot(N, dIdx) * N - dIdx;
-			*domega_in_dy = 2 * dot(N, dIdy) * N - dIdy;
+#ifdef __DNDU__
+			/* as described in pbrt */
+			float3 dndx = sd->dNdu * sd->du.dx + sd->dNdv * sd->dv.dx;
+			float3 dndy = sd->dNdu * sd->du.dy + sd->dNdv * sd->dv.dy;
+			float3 dwodx = -dIdx;
+			float3 dwody = -dIdy;
+			float dDNdx = dot(dwodx, N) + dot(I, dndx);
+			float dDNdy = dot(dwody, N) + dot(I, dndy);
+			*domega_in_dx = dwodx + 2.f * (dot(I, N) * dndx + dDNdx * N);
+			*domega_in_dy = dwody + 2.f * (dot(I, N) * dndy + dDNdy * N);
+#else
+			*domega_in_dx = 2.0f * dot(N, dIdx) * N - dIdx;
+			*domega_in_dy = 2.0f * dot(N, dIdy) * N - dIdy;
+#endif
 #endif
 			/* Some high number for MIS. */
 			*pdf = 1e6f;
diff --git a/intern/cycles/kernel/geom/geom_curve_intersect.h b/intern/cycles/kernel/geom/geom_curve_intersect.h
index e9a149ea1ab..7abae17058e 100644
--- a/intern/cycles/kernel/geom/geom_curve_intersect.h
+++ b/intern/cycles/kernel/geom/geom_curve_intersect.h
@@ -915,6 +915,10 @@ ccl_device_inline float3 curve_refine(KernelGlobals *kg,
 	sd->dPdu = tg;
 	sd->dPdv = cross(tg, sd->Ng);
 #endif
+#ifdef __DNDU__
+	sd->dNdu = make_float3(0.0f, 0.0f, 0.0f);
+	sd->dNdv = make_float3(0.0f, 0.0f, 0.0f);
+#endif
 
 	if(isect->object != OBJECT_NONE) {
 #ifdef __OBJECT_MOTION__
diff --git a/intern/cycles/kernel/geom/geom_motion_triangle_shader.h b/intern/cycles/kernel/geom/geom_motion_triangle_shader.h
index 4789137d5b0..588bf658ac9 100644
--- a/intern/cycles/kernel/geom/geom_motion_triangle_shader.h
+++ b/intern/cycles/kernel/geom/geom_motion_triangle_shader.h
@@ -94,6 +94,7 @@ ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals *kg,
 	sd->dPdu = (verts[0] - verts[2]);
 	sd->dPdv = (verts[1] - verts[2]);
 #endif
+	
 	/* Compute smooth normal. */
 	if(sd->shader & SHADER_SMOOTH_NORMAL) {
 		/* Find attribute. */
@@ -116,6 +117,16 @@ ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals *kg,
 		float v = sd->v;
 		float w = 1.0f - u - v;
 		sd->N = (u*normals[0] + v*normals[1] + w*normals[2]);
+#ifdef __DNDU__
+		sd->dNdu = (normals[0] - normals[2]);
+		sd->dNdv = (normals[1] - normals[2]);
+#endif
+	}
+	else {
+#ifdef __DNDU__
+		sd->dNdu = make_float3(0.0f, 0.0f, 0.0f);
+		sd->dNdv = make_float3(0.0f, 0.0f, 0.0f);
+#endif
 	}
 }
 
diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h
index 105aee8da15..7219587ec03 100644
--- a/intern/cycles/kernel/geom/geom_triangle.h
+++ b/intern/cycles/kernel/geom/geom_triangle.h
@@ -104,6 +104,19 @@ ccl_device_inline void triangle_dPdudv(KernelGlobals *kg, int prim, ccl_addr_spa
 	*dPdv = (p1 - p2);
 }
 
+ccl_device_inline void triangle_dNdudv(KernelGlobals *kg, int prim, ccl_addr_space float3 *dNdu, ccl_addr_space float3 *dNdv)
+{
+	/* load triangle vertices */
+	const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
+	float3 n0 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x));
+	float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y));
+	float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z));
+
+	/* compute derivatives of N w.r.t. uv */
+	*dNdu = (n0 - n2);
+	*dNdv = (n1 - n2);
+}
+
 /* Reading attributes on various triangle elements */
 
 ccl_device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 26d3fcf15b2..ed9a917ff2d 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -10

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list