Houdini Expressions & Functions

Houdini expressions are functions available to help you calculate values in the parameters of the nodes. You may have seen \$HIPNAME which returns the name of the current hip file. Or the centroid one that I use most often for procedural modeling, \$CEX \$CEY \$CEZ, which returns the centroid vector component.

This blog post will explore a few math functions used in Houdini Expressions.

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

I’ll also review the @ptnum which is actually VEX attribute in Houdini, but is used in combination with the rand() function in Houdini Expression.

@ptnum (point number)

I do admit these functions look more like its for coding, but Houdini expressions are used in the parameters of the nodes. You get the best thing of both worlds when using functions and expressions in Houdini. You get the convenience of pre-coded functions and the convenience of using it in parameter values for Houdini’s nodes without actually writing any code.

Fit Range Function

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

The fit function will try to fit a number from one range to another range. For example, if you try to fit the decimal number 50, which represented the grey color from a black and white color ramp. Suppose you want to use 50 to represent the height values on a terrain.

Height Field Terrain in Houdini

This is how height maps work, which is essentially a texture map. Black colored areas in the image represent the lowest heights on a terrain and the white areas can represent the highest points in the height on the terrain. (Previous blog post on texture maps)

Where did 50 come from?

This is important when it comes to using the fit range function, because we need to specify the “oldmin” and “oldmax” parameters in the fit function. You need to know where the value came from in order to find the original range.

In this example, 50 is representing the height values on a terrain. Suppose the largest number for my height terrain is 100 and the lowest height I have is 0, so the number 50 will be the 50% mark in a 0 to 100 range.

num = 50
oldmin = 0
oldmax = 100

But I want to convert the height number 50 to a grey scale color value so I can generate a texture map. This is a case where the fit() function can be useful.

fit(50, 0, 100, 0, 1) = 0.5

This will return 0.5 because 0.5 is the 50% mark in the range of 0 to 1 range. Let’s say I have a height value of 30:

fit(30, 0, 100, 0, 1) = 0.3

It’s important to return all the height values to the new range, 0 to 1, because color values use the 0 to 1 range in Houdini.

What if I’m not using Houdini? I need CSS color codes.

CSS rgb function uses the range 0 to 255. Then if we want to fit our height value of 50 to the CSS rgb colors:

fit(50, 0, 100, 0, 255) = 127.5

I used CSS markup language as an example. I don’t think it’s possible to use Houdini to export to CSS. I just couldn’t think of a better example.

Point Number

Every point in Houdini is assigned a positive number and starts counting from 0. The purpose is to use points numbers to easily identify certain points when needed. In a previous blog post, I use the point numbers to help write VEX code to procedural model a bottle.

Point Numbers are unique, every point has its own number, however points from different nodes are not unique. All points on each node have point numbers starting from 0 and sequentially counting up. The fact that all point numbers are unique within the node is often used for the random function in Houdini for the seed value.

Random Function

rand(value)

Returns a pseudo-random number from 0 to 1.

The rand() function expects a seed value as a parameter, if you provide the rand() function with the same seed value, it will always return the same random number.

For example:

rand(5) = 0.20504

No matter how many times I use this rand(5) function, it will always return 0.20504. The only time this function returns a different result is when I change the input seed value.

rand(50) = 0.45122

Point Numbers are always unique, as mentioned in the previous paragraph titled, Point Numbers. This makes it perfect for seeding the rand() function.

rand(@ptnum) = always different because @ptnum is unique

This results in a different random value for every point.