Component Shaders
Fast Scatter
This is the main shader that does the actual scattering. It is
highly modular and works with several plug-in shaders, and it can
even be cascaded into itself for multi-layer scattering (as is done
in misss_fast_skin_phen).
It layers the results from the plug-in shaders with the scattered
light from the lightmap (optionally nonlinearly, in what is known
as "screen" transfer mode in various compositing applications) and
presents the result as a final composited color.
misss_fast_shader
color "misss_fast_shader" (
color texture "lightmap",
color texture "depthmap",
shader "bump",
shader "diffuse_illum",
color "diffuse_color",
shader "specular_illum",
scalar "diffuse_weight",
color "front_sss_color",
scalar "front_sss_weight",
scalar "front_sss_radius",
color "back_sss_color",
scalar "back_sss_weight",
scalar "back_sss_radius",
scalar "back_sss_depth",
scalar "scale_conversion",
boolean "screen_composit",
boolean "output_sss_only",
scalar "falloff",
integer "samples",
)
apply material
version 4
- lightmap
depthmap
- are the light and depthmap pair from which to extract the data.
For more details, read about misss_lightmap_write and the section
on Automatic lightmap
generation.
- bump
- is a shader that perturbs the normal. While one could use a
shader list and something like mib_bump_passthrough before
this shader, for large scattering radii it is preferred that the
shader is aware of the normal vector before bump mapping. When a
bump mapping shader is assigned to this parameter instead,
misss_fast_shader will
know the normal both before and after bump mapping.
- diffuse_illum
- passes any normal illumination shader (returning a color) for
the diffuse illumination, generally a named shader based on
mib_illum_lambert. If
nothing is passed, it automatically defaults to Lambert.
- diffuse_color
- is an overall color that is applied to all diffuse light,
including the scattered contributions.
- specular_illum
- passes any normal illumination shader (returning a color) for
the specular and reflective components. If nothing is passed, no
specular shading happens. This is layered on top of any diffuse
contributions.
- diffuse_weight
- is a simple scalar multiplier for the color returned by the
diffuse_illum shader, for easier tweaking.
- front_sss_color
front_sss_weight
- are the color and weight for the front surface scattering.
- front_sss_radius
- is the scatter radius in the front surface. Light will scatter
this distance (in whatever units the model is made) along the
surface.
- back_sss_color
back_sss_weight
- are the color and weight of the back surface (or through)
scattering.
- back_sss_radius
- is the scatter radius and back_sss_depth the depth
in the back surface. Generally, the radius and depth are set to the
same value (and if the depth is not specified, it defaults to the
radius) but can be set separately for increased control.
- scale_conversion
- is a simple utility function allowing linear division of all
distances. Since scattering is distance dependent, loading a
material designed for a model made in inches will not work on a
model where the unit is meters, and vice versa. Here one can pass
the conversion factor.
- screen_composit
- when turned on, chooses Screen compositing. When simply adding
together the contribution of many layers of light, it is very easy
to quickly blow out and overexpose into white, but the human eye is
inherently nonlinear and perceives intensities in a different way.
This option allows use of what is known in many compositing
applications as a screen transfer mode between the layers, which
yields a softer, more pleasing result. If it is turned off, normal
addition is used. If rendering in a high dynamic range, and a
proper tone-operator is applied in the final output stage already
compressing the final luminance, use off. If not, turning this
option on yields a more pleasing result.
- output_sss_only
- is for debugging and testing or for preparing for external
compositing; If it is on, only the scattered contribution is
shown.
- falloff
- sets the shape of the distance falloff along the scatter
radius. Higher values yield a sharper falloff, and lower values a
smoother falloff, but also make the perceived scatter distance
shorter, so one must compensate by increasing the actual scatter
distance for a slightly softer look. For high values (1.0 to 10.0),
almost all samples within the scatter radius are weighted equally.
For low values (0.1 to 1.0), the samples near the edge of the
scatter radius are weighted a less.
- samples
- sets how many samples from the lightmap are considered
(maximum) per rendered ray, ideally, a power of two. 32 is probably
the lowest useful value, 128 is plenty.
misss_fast_shader_x
struct {
color "result", # composited color
color "diffuse_result", # diffuse layer
color "diffuse_raw",
color "diffuse_level",
color "specular_result", # specular is not altered by the shader, but
# passed through from "specular_illum" sub-shader
color "front_result", # the "front" SSS layer
color "front_raw",
color "front_level",
color "back_result", # the "back" SSS layer
color "back_raw",
color "back_level"
}
"misss_fast_shader_x" (
color texture "lightmap",
color texture "depthmap",
shader "bump",
shader "diffuse_illum",
color "diffuse_color",
shader "specular_illum",
scalar "diffuse_weight",
color "front_sss_color",
scalar "front_sss_weight",
scalar "front_sss_radius",
color "back_sss_color",
scalar "back_sss_weight",
scalar "back_sss_radius",
scalar "back_sss_depth",
scalar "scale_conversion",
boolean "screen_composit",
boolean "output_sss_only",
scalar "falloff",
integer "samples"
)
apply material
version 4
This shader has identical behavior to misss_fast_shader but provides individual components of the
shading results as output values before compositing them into the
final color value. This supports multi-channel rendering approaches
where compositing is performed in external packages.
The misss_fast_shader
works conceptually with the layering of several light
contributions, all stacked on top of each other. The actual
compositing can be done with simple addition or with the softer
looking screen compositing.
Conceptual layering of misss_fast_shader
Plug-in shaders provide the actual contribution for the various
layers. bump, diffuse_illum and
specular_illum are the main plugin shaders that provide
the shading model.
The bump shader affects the surface normal and is
called before the "... _illum" shaders and hence affects
their shading. However, no bump mapping is performed on the
scattered light, since this happens under the surface. It is
possible to include the effect of bump mapping in the light
before it is scattered by including a bump map shader in the
lightmapping phase.
To create the subsurface scattering itself, light from specially
prepared lightmaps is gathered, weighted by distance, and tinted.
The whole stack is finally layered together as follows, from top to
bottom.
- Layer 1: What the specular_illum shader
returns.
- Layer 2: What the diffuse_illum shader returns.
- Layer 3: The front layer, which is the scattering within the
facing side of the object.
- Layer 4: The back layer, which is light shining through the
object.
The following two observations are noteworthy: First, keep in
mind that the contributions from layers 2, 3 and 4 are all
multiplied with the " diffuse_color" parameter as an
overall tinting and attenuation color for the diffuse
contributions. Second, since the plugin shaders are simply called
and layered in, it is possible to cascade several shaders together
to create multiple layers as follows:
Cascading of misss_fast_shader
This graph shows how a 2nd iteration of misss_fast_shader is used as the
diffuse_illum parameter of the 1st. This works because the
scattering function receives its diffuse illumination from the
lightmaps, and does not care about what diffuse_illum
actually returns. It simply layers it into the mix.
This is precisely how the skin Phenomenon is implemented. A
second shader is cascaded into the first, giving an extra layer. In
principle, there is nothing preventing the stacking of an arbitrary
number of shaders.
Lightmap Creation
This is the lightmapping shader. It is required for the fast
subsurface scattering to work [1]. It
creates a lightmap and stores the front and back surfaces, their
depth, and irradiant light intensities in one or more specially
formatted lightmaps. Two modes of behavior are supported:
- Passing a single writable texture that must be floating point
(32 bits) to the lightmap parameter.
- Passing a lightmap_group and a lightmap_size,
causing the internal creation of an in-memory light and depthmap
pair. To use this option, the shader must be enclosed in a
Phenomenon where the lightmap and depthmap are the first two
parameters. See Automatic
lightmap generation.
misss_lightmap_write
struct {
vector "point",
vector "normal"
}
"misss_lightmap_write" (
color texture "lightmap",
color texture "depthmap",
string "lightmap_group",
scalar "lightmap_size",
integer "write_lightmap",
scalar "scatter_bias",
shader "input"
)
version 4
apply lightmap
- lightmap
- should point to a writable color texture and
depthmap be unassigned or both should be assigned to a
pair of Phenomenon interface parameters as detailed in Automatic lightmap
generation.
- lightmap_group
- is a string with a scatter group name with automatic lightmap
generation. All objects and materials that use the same scatter
group will scatter light into each other.
- lightmap_size
- is the size, in percent of render size, for the automatically
generated lightmap.
- write_lightmap
- is currently reserved for future use.
- scatter_bias
- adjusts the light in the lightmap to favor back scattering
(light from behind the camera scatters back towards the camera)
when using negative values and forward scattering when using
positive values. The technical range is -1 to 1, but generally only
small values (-0.2 to 0.2) make visual sense.
- input
- is the shader that actually samples the lighting in the model
for the lightmap. Generally misss_lambert_gamma is used, but any
illumination shader can be used, for example mib_illum_lambert or even experiment
with mib_illum_phong and
scattering of specular reflections.
Lambert Illumination
This is the supplied lightmap sampling shader. Any illumination
shader can be used like mib_illum_lambert but this one is
specially tuned for the job and has additional options for lightmap
gamma correction, normal flipping and indirect light inclusion.
misss_lambert_gamma
color "misss_lambert_gamma" (
color "ambient",
color "ambience",
color "diffuse",
boolean "indirect",
scalar "diffuse_curve",
integer "flip",
integer "mode",
array light "lights"
)
version 4
apply texture
- diffuse
- is the diffuse color.
- ambient
ambience
- are multiplied with each other to yield a final contribution of
ambient light.
- indirect
- if on, will cause indirect illumination (such as final
gathering and photons) to be included in the lightmap, at the
expense of increased rendering time.
- diffuse_curve
- is the gamma curve for diffuse light. The Lambertian cosine is
raised to the power of this value (i.e. pow(dot_nl,
diffuse_curve)) to flatten (for values less than 1.0) or narrow
(for values above 1.0) the curve for greater control.
- flip
- can be one of the following: 0, normals are not flipped; 1,
normals are flipped; or 2, both the unflipped and flipped-normal
sides are lightmapped. This can be useful for translucency in thin
objects such as leaves.
- mode
- is the mode selector for the light lists.
- lights
- list of lights directly linked to the shader.
Specular Skin
This is a function geared towards recreating the peculiar
specular characteristics of skin. It contains two specular
highlights and glossy reflections with edge enhancement.
The shader can be used anywhere where specular highlights are
needed. It has no diffuse component and hence needs to be layered
together with another shader that provides the diffuse shading.
misss_skin_specular
color "misss_skin_specular" (
scalar "overall_weight",
scalar "edge_factor",
color "primary_spec_color",
scalar "primary_weight",
scalar "primary_edge_weight",
scalar "primary_shinyness",
color "secondary_spec_color",
scalar "secondary_weight",
scalar "secondary_edge_weight",
scalar "secondary_shinyness",
scalar "reflect_weight",
scalar "reflect_edge_weight",
scalar "reflect_shinyness",
boolean "reflect_environment_only",
integer "mode",
array light "lights"
)
version 4
apply material
- overall_weight
- is the overall level of specularity and reflections. Generally,
any specularity map is included here and will affect the level of
all specularity options that follow below.
- edge_factor
- sets the edge width of the edge reflection effects. Skin
reflects more when watched in angles nearly perpendicular to it
(known as a "Fresnel effect") and this parameter sets the
narrowness of this edge. Higher values yield a thinner edge. This
edge width applies to all the edge weights listed below.
- primary_spec_color
primary_spec_weight
- are the color and base weight for the first layer of
specularity. The skin specularity functions are two-layered,
allowing simulation of both the broad soft specularity of skin and
any near-reflective specularities of top layer oiliness and
wetness.
- primary_edge_weight
- sets the additional multiplier for the edge, where final
specularity at the edge is the sum of weight and
edge weight.
- primary_shinyness
- is the specular exponent (higher values yield a smaller and
sharper specular highlight, which is a modified Phong with edge
softening).
- secondary_spec_color
secondary_spec_weight
secondary_edge_weight
secondary_shinyness
- work exactly like the parameters that begin with
primary_ and are for the second layer of specularity.
- reflect_weight
reflect_edge_weight
- the weight and edge weight for reflections. If it is nonzero,
then actual (glossy) reflections are added.
- reflect_shinyness
- is the shinyness value for glossy reflections. When it is 0.0,
standard raytraced mirror reflections are used, but for nonzero
values glossy reflections are generated, which increases render
time.
- reflect_environment_only
- if true only the current environment map is sampled for
reflections, and no actual rays are traced.
- mode
- is the mode selector for the light lists.
- lights
- array of lights directly linked to the shader.
Call Shader
This is a utility "pass through" shader for Phenomenon building.
It allows passing shaders as parameters to material Phenomena for
items such as environment, photons, and displacement.
misss_call_shader
color "misss_call_shader" (
shader "shader",
shader "default_shader",
integer "mode"
)
version 2
apply material, texture, environment, photon, shadow, displace
- shader
- is the shader to be called.
- default_shader
- is the shader that is called if shader is not
specified.
- mode
- is the shader calling mode, where 0 is "automatic". Any other
number maps to a shader calling mode miShader_type. See the
shader.h include file.
Here is an example in pseudo code of using this shader in a
Phenomenon:
declare phenomenon
material "my_phenomenon" (
color "my_special_color",
scalar "my_size",
shader "optional_environment",
...
)
shader "default_environment" "...." (
.... some environment shader ...
)
shader "env" "misss_call_shader" (
# call the passed shader
"shader" = interface "optional_environment",
# if none was passed, call our default
"default_shader" "default_environment"
)
environment = "env"
end declare
The sample shader,
misss_lambert_gamma is optional. Any illumination shader can
be used.
Copyright (©) 1986-2009 by
mental images GmbH