On this page


Houdini communicates with renderers through the SOHO (Scripted Output of Houdini Objects) Python bindings. All renderers use the same process for parameter definition and evaluation. The Mantra and RenderMan output drivers are now simply front-ends to Python scripts (they are now digital assets). Each renderer can add its own parameter definitions and bindings using Python mappings.

SOHO provides two main benefits:

  • Easy to define new render output nodes for alternative renderers. SOHO provides the interface to interrogate Houdini for necessary information to output the renderer-specific file format.

  • You can customize generation of render output by creating a new render node and customizing the soho_program parameter (see below). In some cases this may be more convenient or flexible for you than adding rendering properties to lights, cameras, and/or render nodes.

The SOHO interface is used to send geometry, object transforms, and rendering properties to a renderer. Each supported renderer has a set of predefined rendering properties. If an object has any of these properties defined as spare parameters, its value will be sent to the renderer.

There are a set of predefined rendering parameters which can be added to objects (or materials) using the “Edit Rendering Parameters” interface. There is a one to one mapping of these parameters from the Houdini interface to the renderer’s properties.

SOHO uses the new Material workflow to process shaders and rendering properties. For more information, see the materials and property overrides help.

The SOHO renderer property default values correspond to the target renderer’s default values. If the property value is left at the default value, the property is generally not written out to the input stream for the renderer.


Changing the default value is not recommended, since SOHO and the renderer will no longer be in agreement.

How it works

If you look at the type properties of the Mantra render output digital asset, you will see an invisible parameter called soho_program, which contains the Python script Houdini will run to write the output file (in the case of the Mantra driver, an IFD file).

The Python script will contain code like this:

value = obj.getDefaultedFloat('vm_displacebound', 0.0)

(or, more likely, batch evaluation of properties). When a SOHO program evaluates a parameter like this, it applies the property inheritance order so more specifically-defined properties (for example, on a shader) have priority over more broadly-defined properties (for example, on the output driver node).

The SOHO API and implementation are in Python scripts in $HFS/houdini/soho.

You can use the following parameters to control the SOHO generation process.


The Python script to run. In this script you import soho and use the SOHO API to interrogate Houdini.


What to do with the printed output of the script.


Send output to the pipe command referenced in the soho_pipecmd parameter (see below). Use this mode if you want to pipe the output of the script to another command (e.g. another script or the renderer itself).


Send output to the file referenced in the soho_diskfile parameter (see below). Use this mode if you want to write the output of the script to a file.


Don’t do anything special with stdout. Use this mode if you want to decide how and where to output in the script, rather than in Houdini.


When soho_outputmode is 0, Houdini will run this program and pipe the output of the script to it.


When soho_outputmode is 1, Houdini will redirect the output of the script to this file.


What type of compression to use when writing the script file. Possible values are:

none: No compression will be used. ext: Use the file extension on the soho_diskfile to determine the compression type. If the file extension is .sc, BLOSC compression will be used. If the file extension is .gz, gzip compression will be used.

Compression will only be performed when writing to a disk file, unless the soho_force_compression parameter is set.


Force evaluation of the soho_compression property even when writing to a pipe.


If true, blocks Houdini until the script completes. This is turned on automatically when rendering multiple frames to prevent all frames from rendering simultaneously.


If true, Houdini initializes simulation nodes. This will cause all particle and dynamics networks to start cooking from the first frame to the current frame.

This is used when you are controlling which frames to render (see soho_multiframe below). If you render frame 30 and then render frame 31, you don’t want to initialize the sims (thereby resimulating frames 1-30). On the other hand, if you are rendering frame 31 first, you do want to initialize the sims to properly set up the simulations states for frame 31.


When off (the default), Houdini runs the script separately for every frame. If this parameter is on, the script is run once, and the script is responsible for rendering the frame range itself.


When off (the default), Render to MPlay button will be hidden.

How to show all available properties

See the render property documentation for information about the render properties.

To get mantra to dump a list of properties it knows about, use the ray_show command. It takes an argument representing the category of properties to print.

echo ray_show device | mantra
echo ray_show global | mantra
echo ray_show object | mantra
echo ray_show light | mantra
echo ray_show image | mantra
echo ray_show fog | mantra


SOHO supports callback functions, or hooks to allow advanced users to modify or replace low-level parts of the render process.

(In previous versions of Houdini, it was possible to “monkey patch” SOHO functions as a means of changing SOHO functionality. However, the callbacks are a much cleaner and future-proof method.)

See $HFS/houdini/soho/IFDhooks.py or $HFS/houdini/soho/RIBhooks.py for documentation.

Here’s a sample hooks file:

    A simple example to illustrate the IFDhooks features
import traceback
from IFDapi import *

def pre_lockObjects(parmlist, objparms, now, camera):
    ''' Called before SOHO locks objects.  This allows you to modify the
        objects that are visible to SOHO '''
    ray_comment('IFD Hook - rendering from camera: %s' % repr(camera))
    return False

def pre_render(camlist, now, objlist, lightlist, spacelist, foglist,
                fromlight, forphoton, cubemap, photoncam):
    ''' Called before an image gets rendered '''
    ray_comment('IFD Hook - Render at time: %g %s' % (now, repr(camlist)))
    return False

''' List of hooks in this file '''
_HOOKS = {
    'pre_lockObjects'   : pre_lockObjects,
    'pre_render'        : pre_render,

def call(name='', *args, **kwargs):
    ''' Hook callback function '''
    method = _HOOKS.get(name, None)
    if method:
            if method(*args, **kwargs):
                return True
                return False
        except Exception, err:
            ray_comment('Hook Error[%s]: %s %s' % (name, __file__, str(err)))
            ray_comment('Traceback:\n# %s\n' %
    return False


Mantra user guide



Next steps


Other renderers