Houdini 12 VEX VEX contexts

The shading contexts share many common attributes. Each context represents a different stage in the rendering pipeline. Displacement shading is done first, followed by surface shading, then fog/atmosphere shaders. During surface and fog shading, light and shadow shaders may be run in order to compute illumination.

Note

All available variables in all the shader contexts are in world (camera) space.

Area sampling

The following functions can perform area sampling using the area and samples keywords:

For area sampling, you must specify both the angle and sample parameters. For example:

surface
blurry_mirror(float angle = 3; int samples = 16; float bias=0.05)
{
Cf = reflectlight(bias, 1, "angle", angle, "samples", samples);
}

Global variable access in shading contexts

Each shading context is responsible for setting or modifying different variables. For example, the displacement context can modify the position of the surface being rendered, while the light context is responsible for setting the color of the light source. The Read/Write access of the global variables for each context is summarized in this table.

Variable Type Description Displacement Surface Light Shadow Fog
Cf vector

The final color for the surface. The vector represents the RGB color for the surface.

- W - - R/W
Of vector

The final opacity for the surface. A value of {1,1,0} will be opaque in red/green, but let through blue light from behind. See opacity vs. alpha.

- W - - R/W
Af float

The final alpha for the surface. This is the value which is placed in the alpha channel of the output image. See opacity vs. alpha.

- W - - R/W
P vector

The position of the point on the surface being shaded. In light or shadow shaders, the P variable contains the point on the light source.

Although P is modifiable in the surface context, changing P will not affect rendering of the surface, only shading.

R/W R/W* R R R
Pz float

The Z component of the point being shaded.

R R - - R
Ps vector

In light & shadow shaders, this is the position of the point on the surface being illuminated.

- - R R -
I vector - R R R R
Eye vector

The position of the eye.

- R R R R
s, t float

The parametric S and T (sometimes called U and V) coordinates on the surface being shaded.

R R R R R
dPds, dPdt vector

The delta between the current position (P) and the position of the neighboring micropolygon vertex along S and T. You can use these vectors to get the approximate length of micropolygon edges.

R R R R R
N vector

The shading normal for the surface.

vector R/W R/W R R R
Ng vector

The geometric normal for the surface. This normal represents the “true” normal of the surface being shaded. For example, with Phong shading, the N variable represents the interpolated normal, while the Ng variable represents the true polygon normal

R R R R R
Cl vector

Light color.

- R/W W R/W R/W
L vector

The vector from the point on the surface to the light source. The length of this vector represents the distance to the light source. See how the L variable is initialized.

- R R/W R R
Lz vector

The Z-axis in the space of the light. This is a unit vector.

- - R R -

Optional rendering parameters

Note

When you specify a texture, such as with the "environment" keyword, you can also use the image filtering keyword arguments.

Keyword Functions Description
“scope”, string spec all

Allows an override of the scope for ray-intersections. A special scope argument, scope:self, will match the currently shading object.

“bias”, float value irradiance occlusion

The irradiance and occlusion functions take an optional bias parameter which gives control over self-intersection.

“maxdist”, float value all

Allows an override of the maximum distance the ray can travel when testing for intersections. Some functions (i.e. fastshadow()) have the maximum distance implicitly defined (by the length of the ray) and should probably avoid using this option. However, this option can be used effectively when computing reflections, global illumination, refraction etc.

“variance”, float value reflectlight refractlight fastshadow filtershadow trace

Overrides the global variance control (mantra’s -v option) which is used to determine anti-aliasing quality of ray tracing. For more information please refer to the documentation on mantra.

“angle”, float value reflectlight refractlight fastshadow filtershadow trace

Specifies a cone angle over which samples will be distributed. To be effective, the samples parameter should also be specified. The value is specified in radians.

“samples”, int value

reflectlight refractlight fastshadow filtershadow trace irradiance occlusion

How many samples should be sent out to filter rays. For the irradiance and occlusion functions, specifying a samples parameter will override the default irradiance sampling.

“environment”, string map reflectlight refractlight trace irradiance occlusion

If the ray sent out to the scene misses everything, then it’s possible to specify an environment map to evaluate.

Using the ray’s direction, the environment map specified will be evaluated and the resulting color will be returned. Most likely, it will be necessary to specify a transform space for the environment map evaluations.

In the case of refractlight and trace the Of and Af variables will be set to 0 regardless of the background color specified. the resulting color.

When an environment map is specified, the filtering options from texture() are also supported.

See how to create an environment/reflection map.

“envobject”, string objectname

“envlight”, string lightname

“envfog”, string fogname

reflectlight refractlight trace irradiance occlusion

If an environment map is used, the orientation of the environment map can be specified by transforming the ray into the space of another object, light or fog object in the scene. In Houdini, null objects can be used to specify the orientation. For example:

Cf = R*reflectlight(bias, max(R), "environment", "map.rat", "envobject", "null_object_name");

“envtint”, vector color reflectlight refractlight trace irradiance occlusion

If an environment map is used, it’s possible to “tint” the resulting color.

“background”, vector color reflectlight refractlight trace irradiance occlusion

If a ray misses all objects, it’s possible to specify the background color of the scene. In the case of refractlight and trace the Of and Af variables will be set to 0 regardless of the background color specified.

“distribution”, string style irradiance occlusion

Distribution for computing irradiance. The default is to use a cosine distribution (diffuse illumination). The possible values for the style are:

  • nonweighted - Uniform sampling

  • cosine - Cosine weighted sampling

See irradiance and occlusion for issues related to this keyword.

Optional intersection scoping parameter

When sending rays, the list of objects to intersect against are typically limited by a “scope”, set in the Houdini UI. For example, sending a reflection ray will limit the objects which are tested for ray-intersection to the objects which match the reflection mask of the reflective object.

You can override which objects to test in the following functions:

Function Default light/shadow scope Default surface shader scope
fastshadow() Light’s shadow scope Object’s reflection scope
filtershadow() Light’s shadow scope Object’s reflection scope
rayhittest() Light’s shadow scope Object’s reflection scope
reflectlight() Object’s reflection scope Object’s reflection scope
refractlight() All objects (scope = “*”) All objects (scope = “*”)
trace() Object’s reflection scope Object’s reflection scope
irradiance() Object’s reflection scope Object’s reflection scope
occlusion() Light’s shadow scope Object’s reflection scope

For example,

Cr = reflectlight(bias, max_contrib, "scope", "geo1,geo2");
...will only cause objects “geo1” and “geo2” to be picked up in the reflections.

All Houdini scoping patterns (excepting group expansion) are supported:

  • * - wild-card match

  • ? - single character match

  • ^ - exclusion operator

  • [list] - character list match

An empty string will set the scope to nothing.

Examples:

  • geo* - Matches all objects starting with “geo”

  • geo*,^geo2 - Matches all objects starting with “geo” except “geo2”.

  • leg*,arm[123] - Matches all objects starting with “leg” as well as “arm1”, “arm2”, and “arm3”.

Optional image filter parameters

Keyword Values

wrap or mode

repeat or periodic

The image map will repeat outside the range 0 to 1. Basically, the integer component of the texture coordinate is ignored. This is the default.

clamp or edge or streak

The texture coordinates will be clamped to the range 0 to 1. This causes evaluations outside the range to evaluate to the color at the closest edge of the image (the border pixels are streaked outside the range).

black or decal or color

Coordinates outside the range 0 to 1 will evaluate to the border color (rather than a color in the image). The border color is black (i.e. 0) by default.

uwrap or swrap or smode

Specifies the behavior when the u coordinate is outside the range 0 to 1. The values are the same as with wrap.

vwrap or twrap or tmode

Specifies the behavior when the v coordinate is outside the range 0 to 1. The values are the same as with wrap.

border

Specifies the border color when Black/Decal/Color wrapping is used. The value following this argument should be a float, vector or vector4 argument. If not specified, the border color will be black (i.e. 0) by default.

blur

Blurs in x and y directions. Blur is measured as a percentage of the image size - so a blur of 0.1 will blur 10% of the image width. Use xblur and yblur if you need different blur amounts in either dimension.

xblur, ublur, sblur

Blurs amount in the x image direction.

yblur, vblur, tblur

Blurs amount in the y image direction.

pixelblur, xpixelblur, ypixelblur

Blurs the texture by a floating point number of pixels. Use xpixelblur and ypixelblur if you need different blur amounts in either dimension.

Cf = texture("map.rat", ss, tt, "pixelblur", 2.0);

filter

Specifies the type of anti-aliasing filter to be used for evaluation. The following argument should be a string specifying one of:

point

Point sampling (i.e. no filtering)

box

Box filter (default)

gauss

Gaussian filter

bartlett

Bartlett/Triangular filter

sinc

Sinc sharpening filter

hanning

Hanning filter

blackman

Blackman filter

catrom

Catmull-Rom filter

xfilter or sfilter or ufilter

Specifies the filter for the x direction. The filters are the same as with filter.

yfilter or tfilter or vfilter

Specifies the filter for the y direction. The filters are the same as with filter.

width

A float representing the filter width in both x and y directions. The filter width is used for analytic texture filtering across micropolygons when using micropolygon rendering. Typically you should use a width of 1.

xwidth or swidth or uwidth

A float representing the filter width in the x direction.

ywidth or twidth or vwidth

A float representing the filter width in the y direction.

zwidth

A float representing the filter width in the z direction. This option is only used for deep shadow maps, allowing filtering along the z direction. zwidth is measured in world space units, unlike the other width controls.

extrapolate

Specifies whether derivative extrapolation should be used when computing anti-aliasing information. Extrapolation of derivatives is on by default. The argument should be either 0 or 1.

lerp

Specifies whether RAT files should interpolate between different MIP levels. By default, this is turned off. Turning interpolation on will help remove discontinuities when different MIP levels of a .rat file are accessed. However, the results of texture evaluation will be slightly softer (i.e. blurrier) and will take more time. The argument should be either 0 or 1.

depthinterp

Specifies the depth interpolation mode for deep shadow maps, to control the opacity value that will be returned when the map is sampled between two z-records.

The argument must be a string.

discrete

(default) Return the first z-record before the sample point.

linear

Linearly interpolate the opacities of the z-records before and after the sample point.

See deep shadow maps for more on the difference between the two modes.

Optional light mask parameter

When evaluating light and shadow shaders, objects have pre-defined light masks. This mask is usually specified in the geometry object and specifies a list of lights which are used to illuminate a surface or fog shader. It is possible to override the default light mask by specifying a “lightmask” argument.

For example:

diff = diffuse(nml, "lightmask", "light*,^light2");
...will cause all lights whose names begin with “light” except for a light named “light2” to be considered for diffuse illumination.

All Houdini scoping patterns (excepting group expansion) are supported:

  • * - wild-card match

  • ? - single character match

  • ^ - exclusion operator

  • [list] - character list match

Optional derivative parameters

All functions which compute derivatives take additional arguments to allow tuning of the derivative computation.

“extrapolate”

1 = on, 0 = off (default is 0). Indicates that derivatives are “smooth” across patch boundaries. In most cases this is true and if extrapolation is turned on, derivative computation should be exact for C2 surfaces. However, when the VEX variables are changing with a high frequency (for example, a high frequency displacement map causing high frequency changes to the P variable), extrapolation of derivative computation may cause exaggeration of discontinuities between patch boundaries.

“smooth”

1 = on, 0 = off (default is 1). Adjusts the magnitude of the differentials non-uniformly over patches. This will usually reduce patch discontinuities in displacement/textured shaders. However, in some odd cases you may want to turn this feature off.

N = computenormal(P, "extrapolate", 1, "smooth", 0);

How the L variable is set

This explains how VEX sets the initial value of L (light direction) in the Light and Shadow contexts. Although Houdini provides a value as explained below, you can set L to any value.

In Houdini, lights can have orthographic or perspective projections. An orthographic light represents an infinite (or very distant) light source with parallel light rays. A perspective light represents a point light source with radiating light rays.

When a perspective light shader runs, VEX sets L to P - Ps, where the P variable contains the position of the light source and the Ps variable contains the position of the surface point being shaded.

Orthographic lights, on the other hand, are initialized so that the direction of L is the same for each light ray emanating from the light source: L = Lz * dot(Lz, P - Ps);, where the Lz variable contains the normalized “z-axis” of the light source (that is, a unit vector pointing down the z-axis in the space of the light). So the scale of the L variable will be the orthographic distance from the plane of the light source and the surface point being shaded.

Opacity vs. alpha

In the surface shading context, there are two separate variables to control transparency: Of (opacity) and Af (alpha) are related, but represent different things.

Of represents the opacity of the surface, when mantra resolves surface colors. For example,

Of = {1, 1, 1}

...makes a fully opaque surface the will occlude surfaces behind it.

Of = {0.5, 0.5, 0.5}

...makes a partially transparent surface.

Of = {1, 0, 0}

...makes the surface opaque to red, but pass through green and blue light. This creates a cyan-colored gel.

Af controls the alpha channel of the output pixel in an RGBA image. If a shader doesn’t set Af, mantra uses the default formula,

Af = avg(Of)

However, if you set this variable explicitly, the shader can control the value of the alpha channel of the output image. This lets you write shaders like “matte” or “shadowmatte”.

For example, the following shader simulates a blue screen effect:

surface bluescreen(vector clr=0)
{
    Cf = clr;
    Of = 1;
    Af = 0;
}

The default surface color is black (vector clr=0). The shader sets opacity to 1, meaning this surface will occlude other surfaces. However, the alpha value of the pixels in the output image corresponding to this surface will be 0 (fully transparent).

If you composite the output image over another image, the background image will be visible through the hole this surface left. You can use this technique to, for example, create a window in a wall without modifying the geometry.

You can set Af to a fractional number between 0 and 1 to create partially transparent areas in the output image.

Note

The default for occlusion() is to use closest sample filtering. To handle transparency, pass it the option: “samplefilter”, “opacity”. This is also handled by the environment light asset, using the Transparent Shadows toggle when in Ambient Occlusion mode.

Special variables

There are several “special” variables you can give as parameters to shaders in the shading contexts. Typically, these are export parameters.

__nondiffuse

If this variable is set to a non-zero value, the light shader will not contribute to diffuse illumination in the standard diffuse() functions.

__nonspecular

If this variable is set to a non-zero value, the light shader will not contribute to specular illumination in the standard phong(), blinn(), or specular() functions.

__nofog

If this variable is set to a non-zero value, no fog shaders will affect the surface color.

__illuminateangle

Indicates the angle of illumination for a light or surface shader to the renderer . Angles are measured from the light’s direction to the edge of the illuminating cone. The angle must be specified in radians and should evaluate to a constant expression. For example, the angle cannot depend on varying values such as P or s/t.