[Bf-cycles] Oren-Nayar model revisited
Yasuhiro Fujii
y-fujii at mimosa-pudica.net
Tue Feb 21 15:17:47 CET 2012
Hi all,
A few month ago, I implemented a Oren-Nayar model for cycles. It has a little
wider range of roughness parameter, I noticed that it sometimes generates bad
results. For example, The dark rings are appeared on the spheres.
Essentially, it is caused a bad approximation of O-N model.
In the original paper, Oren and Nayar have proposed two approximate functions
(I call them full O-N and qualitative O-N, respectively). Qualitative O-N is
well known and widely used in CG community but full O-N is less used. I think
full O-N is too complex.
So I developed a tiny improvement of qualitative O-N. It has the same
simplicity as qualitative O-N but yields very similar result as full O-N.
The detail are described at:
http://mimosa-pudica.net/improved-oren-nayar.html
The implementation for cycles is very simple:
__device float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc,
float3 n, float3 v, float3 l)
{
float nl = max(dot(n, l), 0.0f);
float nv = max(dot(n, v), 0.0f);
float t = dot(l, v) - nl * nv;
if (t > 0.0f)
t /= max(nl, nv) + FLT_MIN;
float is = nl * (sc->data0 + sc->data1 * t);
return make_float3(is, is, is);
}
__device void bsdf_oren_nayar_setup(ShaderData *sd, ShaderClosure *sc,
float sigma)
{
sc->type = CLOSURE_BSDF_OREN_NAYAR_ID;
sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL;
sigma = clamp(sigma, 0.0f, 1.0f);
float div = 1.0f / (M_PI_F + ((3.0f * M_PI_F - 4.0f) / 6.0f) * sigma);
sc->data0 = 1.0f * div;
sc->data1 = sigma * div;
}
I've used this model in practice for 2, 3 month and no problems are
found at the moment.
I'd be happy if this improvement is reviewed.
-- Yasuhiro Fujii
More information about the Bf-cycles
mailing list