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
This commit is contained in:
Brecht Van Lommel 2012-02-22 15:04:22 +00:00
parent df83ce61bc
commit 3eaa46e80d

@ -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;
}