There is that interesting paper called “Exploring the potential of layered BRDF models”. Normally people write varnish coats based off that paper, and while I did this as well, I also made a velvet cheat for the 3Delight pathtracing framework (and Paolo Berto keeps saying bidir is very very likely coming… but that’s a tangential note).
S.Westin’s venerable ‘velvet hack’ does certain math tricks to what basically is a Lambertian distribution (computed once for the light vector, once for the normal). The paper above features a simple equation for light absorption in a varnish layer that later attenuates the layer(s) below – which also uses Lambertian-related stuff, but in a different way, with reasoning grounded in actual physics. Those layers are PBS (physically based shading) models, same as the varnish reflection.
In 3Delight, there are several built-in PBS models handled by the trace() shadeop – which is the one to use for pathtracing.
So I looked at all that… and used an inverted “absorption” value from the paper to attenuate an Oren-Nayar built-in model, and made a ‘velvet’ this way. This is a path-traced kitty (the key light is the ‘new’ “trace”-strategy area light; the rest is bsdf() sampling my trusty ole trace()-based GI light – bsdf() is the shadeop for sampling “delta” lights, the “oldschool” sort thereof; but here a path-tracing shadeop is wrapped into an “oldschool” formfactor of an environment light).
I’d say that it looks quite plausible, especially with a little displacement added.
But what about the light vector, you ask, how did you get it from trace()? Well, I didn’t. I didn’t even use it for the bsdf() side of things.
It actually gives very stupid results:
There is a directional light coming from the right, and if you do some math, you’ll see why it gives this ‘spilt paint’ effect. I haven’t figured out any tricks to fix this, so I resorted to using the view vector in both fractions, like the DNA guys (Victor Yudin, I presume) do for the path-traced portion in the Maya 3DLMaterial (yes!! That easy). They do use the L-vector for deltas, but I don’t know what it looks like – I don’t have Maya. Maybe it looks as weird, but nobody uses deltas in Maya anymore, so nobody noticed. Here is how it looks with the V-vector trick and the same directional light. Not the same, but acceptable, IMO. And there’s only one call to the absorption function needed.