John Kunz | Effects Artist
Noise in VEX

John Kunz | March 4th, 2017

This is a short note on generating noise through VEX code as opposed to VOP nodes.



Anti-Aliased Noise

The Anti-Aliased Noise VOP is one of the most commonly used nodes to generate noise, and presents a very simple interface.



The result pictured here was produced by the VOP network below.







To achieve the exact same result using VEX code instead of VOPs, the following code can be used.


#include <voplib.h> vector4 pos = set(v@P.x, v@P.y, v@P.z, 0); v@Cd = vop_fbmNoiseFP(pos, 0.5, 8, 'noise') + 0.5;

The #include directive in the first line of code let's you functions that SideFX has defined in $HFS/houdini/vex/include/voplib.h. Without it, the compiler wouldn't be able to find the vop_fbmNoiseFP() function and throw an error.

Listed below are all the function declarations for vop_fbmNoiseXX().

float vop_fbmNoiseFF(float pos; float rough; int maxoctaves; string noisetype) float vop_fbmNoiseFV(vector pos; float rough; int maxoctaves; string noisetype) float vop_fbmNoiseFP(vector4 pos; float rough; int maxoctaves; string noisetype) vector vop_fbmNoiseVF(float pos; float rough; int maxoctaves; string noisetype) vector vop_fbmNoiseVV(vector pos; float rough; int maxoctaves; string noisetype) vector vop_fbmNoiseVP(vector4 pos; float rough; int maxoctaves; string noisetype)

The first of the last two upper case letters of the function name are used to specify if the function returns a float (F) or vector (V). The second of the last two upper case letters is used to specifiy the dimension of the position argument expected by the function, depending on your needs you could use float (F), vector (V), or vector4 (P).



To see all the functions defined in $HFS/houdini/vex/include/voplib.h, you can open it with a text editor.




Vein Noise

Using a for loop in VEX, it's possible to implement a simple fBm approach and combine several octaves of any arbritary pattern or noise you can think of. This is something that is much more cumbersome to do using VOP nodes, and a case where a code implementation is much more straightforward then a node implementation.



Below is the code used to generate the 'veiny' noise pictured below (inspired by Andy Moorer's blog entry).


vector npos = v@P/1. + set(0., 666., 0.); // Noise input 3D position float namp = 1.; // namp (Noise amplitude) float nval = 0., nweight = 0.; // Init nval (Noise output value), and nweight (Used to normalize octaves) int oct = 9; // Number of Octaves for( int i = 0; i < oct; i++ ) { float __nval = fit(abs(-0.5+noise(set(npos.x,npos.y,npos.z,f@Time))), 0.0, 0.1, 1., 0.); nval += __nval * namp; // Amplitude nweight += namp; // Accumulate weight npos *= 2.132433; // Lacunarity namp *= 0.666; // Roughness } v@Cd = 1 - pow(nval / nweight, 0.8765); // Visualize Noise Output

Offseting the 4th dimension of the noise input coordinates over time produces this evolving motion.