Houdini 20.0 VEX

Writing PBR shaders in VEX

On this page

To build materials using VOPs instead, see building materials in VOPs.


Writing a PBR surface shader involves designing a bidirectional scattering distribution function (BSDF) for the surface. This function describes how light scatters when it hits the surface. BSDFs are an opaque data type in VEX that you can store and operate on much like other primitive types.

You output the final BSDF for the shader through a new global variable F. In VOPs, you connect a BSDF to the F connection of the output node (see VOPs below).

The BSDF is a self-contained description of how a surface reflects light. With PBR, you don’t need to compute illumination (for example, using illuminanceloops or trace() calls). You only need to provide a bsdf.

You don’t have to write the scattering function yourself. You can create BSDFs by combining primitive BSDFs using addition, multiplication, and scalar multiplication. See “primitive BSDFs” and “combining BSDFs” below. If you want, you can write your own BSDF functions using CVEX.

Depending on the settings selected for the render, mantra can use the BSDFs calculated by your shader in many different ways. For example, it may perform direct lighting, indirect lighting, or evaluate lighting in reverse for algorithms like photon mapping.

You can design shaders that support both traditional and physically based rendering. You just need to assign values to both types of output variables (Cf, Of, and Af for traditional rendering, F for PBR rendering) in your shader.

Primitive BSDFs

Combining BSDFs

  • bsdf +(bsdf, bsdf)

    Sum together two bsdfs. Summing bsdfs allows you to include more than one type of component, such as summing together a diffuse() and a phong().

  • bsdf *(float scale, bsdf)

  • bsdf *(vector scale, bsdf)

    Scale a bsdf by a color or a scale factor. Scaling a bsdf can allow you to incorporate surface colors (such as texturing) into the bsdf.

  • bsdf *(bsdf, bsdf)

    Create the produce of two bsdfs. This function is most useful for scaling a specular bsdf by a diffuse().

  • vector albedo(bsdf)

    Return the portion of reflected light for a bsdf. The return value should be between 0 and 1 for bsdfs that conserve energy. The albedo for a default diffuse bsdf is 0.5, but will change based on vector scale factors and other bsdf components.



Next steps