OpenGL shaders are hardware accelerated shaders that are executed on the video card. OpenGL shaders only affect the viewport – they are not rendered. You can create an OpenGL shader and include it in a material to show a better representation of the material in the viewport.
Writing an OpenGL shader
Creating a new shader type
OpenGL shaders are written using GLSL (the OpenGL Shader Language). Before you can create an OpenGL shader you need to understand GLSL and its related concepts such as vertex shaders and fragment shaders.
Choose File > New operator type.
Click on SHOP Type.
In the Network Type menu, choose GLSL Shader.
Enter an internal Name for the shader and a human-readable Label.
Click Accept. The type properties window for the new shader type appears.
Click the Code tab. The node starts with some default shader code. You can use this as a starting point for creating your shader.
The Code tab provides a simple editor for working with GLSL code. The editor has three text boxes: one for the vertex shader, one for the fragment shader, and one for compiler output. You can drag the dividers between the three panes to resize them.
Click Test compile to try compiling the default code. The output of the compiler appears in the third pane.
See the OpenGL GLSL documentation for more information on programming in GLSL.
You cannot currently create a GLSL shader using VOPs.
Houdini built-in functions
Houdini will automatically load and link the following GLSL functions if they are found in the shader code. All the methods are fragment shader specific unless otherwise noted.
Assigns the various RGB lighting components to the output color. Additional
information, such as
Assigns only the diffuse component. All other components are assumed to be zero. Point, Normal and alpha are required for High Quality Lighting and Transparency passes.
Assigns the emission of the object along with the opacity. This is also used when the shader computes its own illumination, or doesn’t want its color affected by further lighting calculations.
All fragment shaders must use exactly one of the HOUassign methods to
write out their color values, instead of directly writing to
Computes the diffuse illumination given point position
Computes the specular and diffuse intensities for all lights in the scene
Computes the ambient, diffuse and specular colors for all lights in the
scene (up to
Returns the normal
Discards the fragment if the fragment fails the depth peel test.
Returns the depth from UV coordinate
Returns the normal from UV coordinate
Houdini automatically generates values for the following uniforms (all prefixed
glH_) which may be used by all shader stages.
An integer that stores the current pass being render. These passes are:
Lighting calculations should only be performed if
The view matrix (not to be confused with OpenGL’s
The inverse of the view matrix (not to be confused with OpenGL’s
An array that indicates which of OpenGL’s lights are enabled.
A vec2 containing the current dimension of the viewport being rendered.
The follow uniforms are available, but generally only used by the
HOUassign() family of built-in Houdini functions. If you do not use them (not recommended) you will need to multiply in the factors, apply the ghost color, handle the depth peeling and two-sided lighting for transparency.
A float that is 1.0 if emission is used in this pass, 0.0 if not.
A float that is 1.0 if specular is used in this pass, 0.0 if not.
A float that is 1.0 if diffuse is used in this pass, 0.0 if not.
A float that is 1.0 if ambient is used in this pass, 0.0 if not.
A vec4 representing the ghosting color for 'ghost other objects' display mode. It is set regardless of whether the current object is ghosted, though the color will be (0,0,0,0) if the object is not ghosted.
An integer that is 1 when depth peeling is active, 0 otherwise.
A 2D texture sampler containing the depth map for depth peeling.
An integer that is 1 when a transparency pass is active, 0 otherwise.
Transparency passes always light the polygon face that is facing the light.
This is used by the
An integer that holds a bitmask of the lights that would affect the
object being rendered. This is used by the
Houdini’s viewport renderer has a large number of display settings which users can change. In some cases the viewport renderer renders multiple passes in order to create a certain visual effect. For example, projective textures and shadows both require multiple passes.
To be compatible with Houdini’s various rendering modes, GLSL shaders should adhere to the following guidelines:
Use one of the
HOUassign...()methods to assign the color output of a fragment shader.
Do GL lighting with
HOUlightDiffSpec(). Otherwise, only add light contributions from enabled light sources. Use the
glH_LightEnableduniform to check which lights are enabled.
The multi-pass viewport render
When writing a GLSL shader in Houdini it is useful to understand the contexts
in which the shader will be executed. The uniform
glH_MaterialPass can be used to query the pass.
|Normal Lighting Pass (0)|
Ambient, diffuse, specular and emission components can all be calculated with full lighting. This may be done with the Houdini lighting functions or by the shader.
|High Quality Lighting Pass (1)|
The raw ambient, diffuse, specular and emissive components of the material should be defined but no lighting calculations should be applied. If a shader does not want to participate in HQ lighting, do the lighting computations and assign it to the emissive component.
|Normal Pass (2)|
Everything but the normal component is discarded.
|Shadow Map Pass (3)|
A shadow map is being created. Only the depth and alpha value are used, so all calculations for color can be avoided.
When shading, the
glH_AlphaPass variable is set to 1 if a transparency pass
is rendering. You may discard the fragment if your material uses transparency
glH_AlphaPass is 0, or if your material is opaque and
glH_AlphaPass is 1.
The OpenGL viewport renderer distinguishes between transparent and opaque
materials. To properly render transparent objects, shaders must provide a hint
to the renderer. Currently you do this by declaring a uniform of type
with the name
Applying an OpenGL shader
|Assign a GLSL shader for the viewport only|
Set an object’s surface shader to an instance of your GLSL shader, or connect an instance of your GLSL shader to the surface color output inside a material.
|Assign both a GLSL shader for the viewport and a shader for the renderer|
|My Geometry is Invisible|
|My Geometry is Not Receiving Shadows|
Some shaders emit light and don’t reflect light (e.g. the decal shader). Such a shader will, by design, not receive shadows.