Shading OpenGL Shaders

Overview

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.

  1. Choose File > New operator type.

  2. Click on SHOP Type.

  3. In the Network Type menu, choose GLSL Shader.

  4. Enter an internal Name for the shader and a human-readable Label.

  5. Click Accept. The type properties window for the new shader type appears.

  6. 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.

  7. 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 auto-uniforms

Houdini automatically generates values for the following uniforms.

glH_InvViewMatrix

The inverse of the view matrix (not to be confused with OpenGL’s modelview matrix).

glH_LightEnabled

An array that indicates which of OpenGL’s lights are enabled. glH_LightEnabled[i] is non-zero if (GL_LIGHT0 + i) is enabled.

glH_ViewMatrix

The view matrix (not to be confused with OpenGL’s modelview matrix).

Coding guidelines

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:

  • Set gl_Position to the result of ftransform() in all vertex shaders, to be compatible with shadow mapping.

  • Modulate material emission values by the glH_Emission uniform.

  • Modulate material ambient values by the gl_LightModel.ambient uniform.

  • Only add light contributions from enabled light sources. Use the glH_LightEnabled uniform 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. Houdini’s OpenGL viewport renderer, used for projective textures and shadows, does five main passes: an emission pass; a global ambient pass; a pass for point, spot, and distant lights; a shadow map pass; and a pass for unlit geometry. GLSL shaders may be executed in all but the last two passes.

Note

Houdini supports light color components that are greater than 1.0; however, OpenGL clamps diffuse, specular, and ambient light values to the range . To overcome this, the multi-pass renderer normalizes these values and then compensates for this normalization at a later stage.

Emission Pass

During the emission pass, the glH_Emission uniform will be 1.0; for all other passes it will be 0.0. In the single-pass renderer, glH_Emission is always 1.0, implying that you should always add an emission term.

Global Ambient Pass

During the global ambient pass, the gl_LightModel.ambient uniform will be a non-zero value. For all other passes it will be (0.0, 0.0, 0.0, 1.0). In the single-pass renderer, gl_LightModel.ambient may be a non-zero value.

Individual Light Pass

During an individual light pass for a point, spot, or distant light, the glH_LightEnabled uniform will indicate which light is enabled; for all other passes, glH_LightEnabled will indicate that no lights are enabled.

Shadow Map Pass

GLSL shaders do not execute during the creation of shadow maps. You must set gl_Position to the result of ftransform() (for the other passes) or invalid shadow maps may be generated. See the coding guidelines above.

Unlit Pass

This pass is not relevant to GLSL shaders.

Transparency

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 float with the name "ogl_alpha". The multi-pass renderer does not support transparency at this time.

Applying an OpenGL shader

To... Do this

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

  • You can define both GLSL shader code and VEX or RenderMan code in a GLSL shader type. Houdini will use the GLSL code in the viewport and the VEX/RenderMan code in the render.

    On the Code tab, click the gear menu and turn on VEX/RenderMan shader. This creates another tab where you can write VEX or RenderMan shader code.

  • You can also connect both an OpenGL shader and VEX surface shader to the surface color output of a material using a Select shader node.

Troubleshooting

My Geometry is Invisible

  • Note that transparency is not supported in the multi-pass renderer at this time.

  • Make sure that your GLSL shader compiles.

    Right click the shader node and choose Type properties. Click the Code tab. Click Test compile to try compiling your shader code and check for errors.

  • Some GLSL shaders require vertex attributes to be passed to them (e.g. the tangent space normal mapping shader). Make sure you are passing it the correct data.

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.