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