The Vault Manual

A quick collection of useful snippets and workflows
that make every day a little bit faster in Houdini.


Camera Cull

This handy little snippet can be used to quickly create a camera cull in VEX. I use this all the time. Just remember to change the cam parameter to an operator path instead.

string cam = ch("cam");

float buf = ch("buf");

vector ndc = toNDC(chs("cam"),@P);

if(ndc.x<-buf || ndc.x>(1+buf) || ndc.y<-buf || ndc.y>(1+buf) || ndc.z>0){



Looping value from 0-1

Recently found this digging around in some vex code. Pretty handy. Pasting here for future reference.

@timeloop = (@Time%2)/2;

Attribute from other input

This is how you access an attribute from another input in an attribute wrangle. In this case. From the second input, accessing the @P value.

@P = point(1, "P" , @ptnum);

Point in centre of an object

Many times it’s very handy to get a point in the centre of an object. I like to use a wrangle to do this using the following code. All you need to do is put the object you want the centre of in the second input. And an “add” sop creating a point.

vector min, max;
vector centre = avg(min,max);

@P = centre;

Using point() expression

To get the position of a certain point you can use the following expression. The first number represents the point number. The second represents the axis. X, Y, or Z:

point("string geometry", 0, "P", 0)

point("string geometry", 0, "P", 1)

point("string geometry", 0, "P", 2)

Delete points based on Colour

This simple VEX code will delete points based on the colour attribute. Remember to click “Spare parameters”.

if (@Cd < ch("threshold")){

Delete points with slider

Delete random points with a slider, including a handy seed slider. If you have “id” attributes, replace @id with @ptnum.

if (rand(@id*ch('seed'))<ch('threshold')) {



Group points with Slider

This handy VEX code will allow you to group points using a threshold value:

if ( rand(@ptnum) > ch('threshold') ) {
i@group_mygroup = 1;

Rotate orient around an axis

I've had the need to rotate the @orient attribute around an axis, you can do so by creating a vector4 where the "set(0,1,0)" controls the axis you want to rotate around. In this example we are rotating around the Y axis. Remember the :

vector4 rot = quaternion(set(0,1,0)*ch("rot"));

@orient = qmultiply(p@orient, rot);


Automatic filepath

Making it easy to write files to a standard location that always keeps up to date is a great way to save time and staying organized. I’ve saved this as my output path by default. This path also references a parameter called “ver”. So I create an Integer slider that is called “ver”. That way you can flick up every time you make changes, but want to keep old caches.


Fit expression in carve sop

Sometimes it’s useful to use the carve sop to create animation from a curve. I like to use this simple fit expression to animate the curve over time based on the current frame.

fit($F, $FSTART, $FEND, 0, 1)

fit(num , oldmin , oldmax , newmin , newmax )

Get output from opinputpath

Quickly grab an input from a connected node: 0 = input 1 / 1 = input 2 etc…


bbox and centroid

Dealing with the fluid container inside a pyro simulation can sometimes be tedious and confusing. This little trick will get the container size from a bounding box using the bbox expression. Assuming you have set up your pyro simulation and created a bounding object all you need to do is to put the bbox code inside the “Size”, and centroid in the “Center” parameter inside your smoke object.

Note that 6 is only the X axis, 7 – Y and 8 – Z. However, the centroid function uses the standard “0 – X, 1 – Y, 2 – Z”

bbox("inputPathToBounding", 6)

centroid("inputPathToBounding", 0)


Connecting detached curves

Need to connect or fuse a spline into one primitive? You can use the “PolyPath” sop to do a spline fuse.

This node replaces all edges with polygon curves that continue until any point connected to three or more other points is reached.
By default, this will reduce any edges that occur more than once to a single edge, and will remove any edges from a point to itself.
It also has various options for cleaning up topology in other ways.

HDA Namespace and versioning

When creating HDA’s it’s smart to use correct namespaces and versioning. Let’s say I am creating an HDA I call “Renderkit”. The correct inputs would be:

Operator Name: AFX::renderkit::1.0

Operator Lable: renderkit

This will make sure Houdini will be able to read the correct version and add them to the list of versions. So that you avoid overwriting older instances. This is important in order to keep your scenes from losing their HDAs in the future.
Read more: