These shaders have great layout flexibility, and use NVIDIA ARCS's MDL as inspiration for its components. What you can see from this diagram:
Extra output passes can be specified using Light Path Expression (LPE) terms. A subset of these LPEs are supported by the layering shaders and can be automatically written to user framebuffers, just by specifying them by their names in the camera. One can also use the global string options to specify which LPE can go to an arbitrarily named user framebuffer. Most typical shading subset outputs (e.g. "diffuse") can be represented, and all separated outputs should linearly add up to the beauty "result" output. Therefore, these additive passes are compositing-ready. The current passes supported include those detailed here: Multiple LPE Passes
The shaders accept several global settings as string options, some for testing, some for refining the functionality.
"light relative scale" | The shader listen to the "light relative scale" with shading matching that of the BSDF's, i.e. it adjusts it's interpretation of lights based on the "light relative scale". To match mia_material shading, "light relative scale" must be 1/PI | "mila ray cutoff" | This is the cutoff importance at which point rays starts to be ignored. It is similar to refr_cutoff in mia_material, except it's here a global setting. The default is 0.01 (i.e. rays contributing less than 1% begins being rejected. | "mila clamp output" | On/off. Enables/disables an output value clamp in mila_material. The default is off. | "mila clamp level" | If the above clamp output is enabled, use this level value to clamp to, roughly as luminance. The default is 1.0. If the output is allowed to go over 1, but needs dynamic range reduction for optimization, try values between 1 and 5; as these depend on scene and pipeline requirements, as well. | "mila quality" | A quality multiplier for all other quality settings in the layering library that follow. This defaults to 1.0. | "mila glossy quality" | Controls the number of samples for glossy reflection or glossy transmission. This defaults to 1.0. That uses a nominal number of samples, that is also controlled by trace depth and importance, as well as roughness in the glossy shader. | "mila scatter quality" | Controls the number of samples for scatter sampling around the hit point. This defaults to 1.0. Nominally about 64 samples if all other factors regarding importance, trace depth, etc. are high. | "mila diffuse quality" | Controls the number of samples for indirect diffuse reflection when indirect diffuse detail is used. This defaults to 1.0. | "mila diffuse detail" | On/off. Enables indirect diffuse detail mode, similar to ao color bleed/fg force for just the mila_diffuse_reflection shading. | "mila diffuse detail distance" | Distance used for detail. Beyond this distance regular indirect diffuse control (GI/FG) is used. | "LPE: XXX" | Now deprecated. Use the framebuffer LPE attribute now. Defines which user framebuffer the Light Path Expression XXX will be written to. Currently supported pass details are here. The string option must begin with "LPE: ", ie a single space after the colon, before the LPE is specified. String option examples based on typical pass names include:
|
"mila share lights" | Can be used for debugging and performance comparison. When off, the light sharing is disabled, and every layer (component) shader will run it's own light loop. The default is on. |
"mila propagate importance" | Can be used for debugging and performance comparison. When off, the importance propagation to subshaders and subrays is disabled, so the impact of this optimization can be judged. The default is on. |
"mila separate interactions" | Used for debugging and performance comparison. Determines whether after the first hit, secondary rays are traced based on probability of a component, ie, its calculated final weight. The default is on. |
This shader MUST be the root shader of the shade tree (otherwise, transparency and shadows will not work at all). It can also optionally write to framebuffers.
declare shader "mila_material" ( # Shader to call shader "shader", # boolean "thin_walled", shader "backface_shader", # scalar "visibility" default 1.0, # # Debug/test tool: Show a given fb as beauty # 1 = ALL, 2 = transparency, 3 = absorb, 4 = LrDE, 5 = LrGE etc. integer "show_framebuffer" default 0, # # overall bump vector for whole material vector "bump", # # Name of framebuffers to output to # If empty, nothing is written array struct "extra_color" { color "color", string "color_fb", boolean "color_comp" }, array struct "extra_vector" { vector "vector", string "vector_fb", boolean "vector_comp" }, array struct "extra_scalar" { scalar "scalar", string "scalar_fb", boolean "scalar_comp" } ) apply material, shadow, photon version 4 end declare
The mila_material root shader requires a single mila_layer or mila_mix as input to the "shader" slot, and the shade tree grows from there.
It also has the following additional inputs
The mila_layer and mila_mix shaders do all the "hard lifting" of layering and mixing. They should only be used either
The shaders will not function properly outside the layering shader system, and may even crash if you attempt to use them elsewhere.
These shaders return a single color output representing the combined shader components input as layers. The mila_layer shader interface is an initial parameter, followed by an array of structs (shown below), one for each layer. Note that when used in some DCC applications, parameter of type "array-of-structs" are not supported in the user interface. To solve this, Phenomena will be provided that expose a fixed sets of layers.
declare shader color "mila_layer" ( array struct "layers" { shader "shader", boolean "on" default on, scalar "weight" default 1.0, #: min 0 softmax 1 color "weight_tint" default 1 1 1 1, boolean "use_directional_weight" default off, integer "directional_weight_mode" default 0, #: enum "fresnel:custom" scalar "ior" default 1.2, scalar "normal_reflectivity" default 0.05, scalar "grazing_reflectivity" default 1.0, scalar "exponent" default 5.0, vector "bump" } ) version 5 end declareThe mila_layer shader uses weight similar to an "over" operation in a compositing system, where the weight represents a percentage of the top layer layered over the top of whatever is below. In other words, the first (topmost) component is used at exactly the weight specified, and anything that comes below is weighted by (1 - weight). This is applied recursively down through the layers in the order they are specified. This behavior is similar to the built in energy conservation of mia_material. The input parameters are as follows:
declare shader color "mila_mix" ( boolean "clamp" default off, array struct "components" { shader "shader", boolean "on" default on, scalar "weight" default 1.0, #: min 0 softmax 1 color "weight_tint" default 1 1 1 1, vector "bump" } ) apply material, texture, shadow, photon version 2 end declareThe mila_mix shader mixes its components, like two paints are mixed together in a bucket. For mila_mix, the component inputs are mostly similar, but without the directional weight dependency. Weight is not interpreted as a percentage like a layer would behave. So, for energy conservation, one other parameter is used to mix with the specified weights as follows: