[Bf-committers] Shading System Proposals
matt at mke3.net
Tue Dec 1 04:10:35 CET 2009
On 01/12/2009, at 2:05 AM, Brecht Van Lommel wrote:
> To get some discussion started, here's two things I'm still unsure
> about, extracting a BXDF from node trees and the future role of the
> texture stack.
>> Matt has also been investigating this, there's some overlap in topics
>> but he has much more detail on various topics:
> Matt proposes a Sample_F output here but it's not entirely clear to me
> how this works, I also couldn't understand from the Houdini
> documentation for example if their BSDF F value is just a
> vector/scalar value or also contains information on how to sample it.
I've done some research on this, and I think I have a fair idea of
what's going on in there. I actually suspect it's quite similar to
what I was toying around with before . Rather than containing
merely values, the brdf type probably contains some function pointers
to pre-made functions (i.e. lambert distribution, phong distribution,
etc), since that's really the only way to represent a Scattering
Distribution _Function_. It also contains some other flags to say what
kind of scattering it can represent (diffuse, glossy, specular,
emission) etc, and probably some custom data to represent bsdf
parameters (like a glossiness slider).
I'm guessing this via a few VEX functions:
* sample_bsdf()  that takes a bsdf, 2d random samples, and shading
geometry as input, and returns an outgoing vector - eg. for lambert a
cosine weighted vector in hemisphere, and
* eval_bsdf()  which takes a bsdf and shading geometry input and
returns a colour (proportion of light that's reflected) - eg for
lambert, L.N .
These above functions would basically just execute the bsdf callbacks
with the input information.
As for how it mixes bsdfs, some ideas are either it somehow
dynamically generates new distribution function callbacks that
represent multiple combined distributions (which i seriously doubt) or
it uses some kind of internal layering/stacking system where it keeps
track of what BxDFs make up the entire BSDF, and with what weights.
> I can think of a few ways to do this using a node tree, doing the
> computation F by evaluating nodes with some entirely or partially
> excluded, and doing sample distribution by picking randomly from
> distributions provided by nodes that contain a BXDF.
You don't want to do it randomly, it should be weighted it based on
layering - a probability per BxDF component. So for example if you're
shading a glass shader with perfect specular BRDF and specular BTDF,
blended via fresnel, then if the incoming ray is at glancing angles,
there's much higher probability (fresnel function) of picking an
outgoing vector based on the BRDF, not the BTDF.
> possibility would be to pass a long a BXDF type through nodes, then
> for example a mix node could create a new BXDF that can do more clever
> importance sampling. Neither seems particularly elegant or transparent
> to the user to me, but I can't think of good alternatives at the
That's basically what Mantra PBR does, explicitly with the bsdf data
type/node connections. The output node has a bsdf input, so for
situations where you just need to find an outgoing scattering
direction, you a) get the final bsdf arriving at the output via the
node tree, and b) pass that final bsdf to the sample_bsdf() function.
The more I understand about this, the more I really think it's the
right way to go. They've really done an excellent job coming up with a
modern system, without the 90s trappings, and with the flexibility of
programmable/editable shading. I'd really like to see Blender head
down that path too as a design that will serve us for the future.
More information about the Bf-committers