diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-02-22 19:04:22 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-02-22 19:04:22 +0400 |
commit | 3eaa46e80d8f3d7c09983438fe5c06e8cd92b397 (patch) | |
tree | ac7a11d0ece532255790ca98e0ba1a6d62b1349a | |
parent | df83ce61bc324115faa7c8b55e17fccbde071191 (diff) |
Cycles: improve the Oren-Nayar BSDF (roughness value for Diffuse), to avoid
undesired dark rings, and give more accurate lighting when the light is
behind the object. As a bonus, the code is simpler & faster.
Patch by Yasuhiro Fujii, detailed explanation here:
http://mimosa-pudica.net/improved-oren-nayar.html
-rw-r--r-- | intern/cycles/kernel/svm/bsdf_oren_nayar.h | 26 |
1 files changed, 6 insertions, 20 deletions
diff --git a/intern/cycles/kernel/svm/bsdf_oren_nayar.h b/intern/cycles/kernel/svm/bsdf_oren_nayar.h index 0ad7cad06bb..81884de8798 100644 --- a/intern/cycles/kernel/svm/bsdf_oren_nayar.h +++ b/intern/cycles/kernel/svm/bsdf_oren_nayar.h @@ -55,25 +55,11 @@ __device float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc, float3 n, { float nl = max(dot(n, l), 0.0f); float nv = max(dot(n, v), 0.0f); + float t = dot(l, v) - nl * nv; - float3 al = normalize(l - nl * n); - float3 av = normalize(v - nv * n); - float t = max(dot(al, av), 0.0f); - - float cos_a, cos_b; - if(nl < nv) { - cos_a = nl; - cos_b = nv; - } - else { - cos_a = nv; - cos_b = nl; - } - - float sin_a = sqrtf(max(1.0f - cos_a * cos_a, 0.0f)); - float tan_b = sqrtf(max(1.0f - cos_b * cos_b, 0.0f)) / max(cos_b, 1e-8f); - - float is = nl * (sc->data0 + sc->data1 * t * sin_a * tan_b); + if (t > 0.0f) + t /= max(nl, nv) + FLT_MIN; + float is = nl * (sc->data0 + sc->data1 * t); return make_float3(is, is, is); } @@ -84,9 +70,9 @@ __device void bsdf_oren_nayar_setup(ShaderData *sd, ShaderClosure *sc, float sig sigma = clamp(sigma, 0.0f, 1.0f); - float div = 1.0f / ((1.0f + 0.5f * sigma) * M_PI_F); + float div = 1.0f / (M_PI_F + ((3.0f * M_PI_F - 4.0f) / 6.0f) * sigma); - sc->data0 = 1.0f * div; + sc->data0 = 1.0f * div; sc->data1 = sigma * div; } |