From 69dc0c319277480dda17d47fa3899b946b965768 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 12 Feb 2016 11:42:33 +0100 Subject: Cycles: Fixes for Burley BSSRDF There are several fixes in here, which hopefully will make the shader working correct without too much magic in there. First of all, this commit brings BURLEY_TRUNCATE down from 30 to 16 which reduces noise a lot. It's still higher than original truncate from Brecht, but this reduces PDF value at a cutoff distance by an order of magnitude (now it's 0.008387, previously it was 0.063521 for the albedo of 0.8 and radius 1.0). This should converge to a proper result faster and don't have artifacts. This kind of reverts fix for T47356, but after additional thinking came to conclusion Burley is not being totally smooth, it is about giving less waxy results which it's kind of doing in the file. Second of all, this commit fixes burley_eval() to use normalized diffusion reflectance. This matches the way we calculate CDF and solves numeric instability close to 0, making PDF profile looking closer to other SSS profiles: https://developer.blender.org/F282355 https://developer.blender.org/F282356 https://developer.blender.org/F282357 Reviewers: brecht Reviewed By: brecht Differential Revision: https://developer.blender.org/D1792 --- intern/cycles/kernel/closure/bssrdf.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'intern/cycles/kernel/closure/bssrdf.h') diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h index 21a4d58598b..a3ca58461ad 100644 --- a/intern/cycles/kernel/closure/bssrdf.h +++ b/intern/cycles/kernel/closure/bssrdf.h @@ -181,8 +181,8 @@ ccl_device void bssrdf_cubic_sample(ShaderClosure *sc, float xi, float *r, float * the mean free length, but still not too big so sampling is still * effective. Might need some further tweaks. */ -#define BURLEY_TRUNCATE 30.0f -#define BURLEY_TRUNCATE_CDF 0.999966f // cdf(BURLEY_TRUNCATE) +#define BURLEY_TRUNCATE 16.0f +#define BURLEY_TRUNCATE_CDF 0.9963790093708328f // cdf(BURLEY_TRUNCATE) ccl_device_inline float bssrdf_burley_fitting(float A) { @@ -195,7 +195,7 @@ ccl_device_inline float bssrdf_burley_fitting(float A) */ ccl_device_inline float bssrdf_burley_compatible_mfp(float r) { - return 0.5f * M_1_PI_F * r; + return 0.25f * M_1_PI_F * r; } ccl_device void bssrdf_burley_setup(ShaderClosure *sc) @@ -215,20 +215,20 @@ ccl_device float bssrdf_burley_eval(ShaderClosure *sc, float r) const float d = sc->custom1; const float Rm = BURLEY_TRUNCATE * d; - if (r >= Rm) + if(r >= Rm) return 0.0f; - /* Clamp to avoid precision issues computing expf(-x)/x */ - r = fmaxf(r, 1e-2f * d); - /* Burley refletance profile, equation (3). * - * Note that surface albedo is already included into sc->weight, no need to - * multiply by this term here. + * NOTES: + * - Surface albedo is already included into sc->weight, no need to + * multiply by this term here. + * - This is normalized diffuse model, so the equation is mutliplied + * by 2*pi, which also matches cdf(). */ float exp_r_3_d = expf(-r / (3.0f * d)); float exp_r_d = exp_r_3_d * exp_r_3_d * exp_r_3_d; - return (exp_r_d + exp_r_3_d) / (8*M_PI_F*d*r); + return (exp_r_d + exp_r_3_d) / (4.0f*d); } ccl_device float bssrdf_burley_pdf(ShaderClosure *sc, float r) -- cgit v1.2.3