[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