Writing custom vector fields is pretty easy in VOPs. You can leverage the multiple noise functions Houdini offers, easily create vortices and whirling clouds, and with just a bit more effort bring in curves and use them as paths which the field can orbit around or follow along. Whip up an additive shader and you can get very nice results… or export the fields to use in Unreal or some other game engine. I plan on eventually offering a number of free static vector fields here on the site for game effects artists, but for now here are some basic test renders, cheers.

A webbing rig, stretches nicely between two controls, lots of user control. Could go a lot further with this of course but I wanted a fast exploration utilizing and testing some of the generic asset’s I’ve made so I probably will leave it here until I feel like doing an animation with it.

This houdini file creates an infinite number of shapes to populate blueprints or info screens, with a “pen and ink” rendering look. It was a lot of fun to make.

In an earlier post I used a very unwieldy approach to get the position of a null in vex. Since then I have used a method where an object_merge SOP is set to transform “into this object” and then a point function can easily read the first point in the null to arrive at a center position. The problem with this is that you are reading the icon geometry for the object and in the case of a null this is ok, but the camera icon has each point offset from it’s origin.

Enter optransform and cracktransform. The optransform function will let you set a path to the camera (or whatever else you may want to use) and then populates a matrix with the target’s transforms. You can then extract out the position as a vector using the cracktransform function… this function if pretty powerful and at first confusing but essentially it has a switch which let’s you specify the portion of the matrix you need.

In the example above I used these functions to get the camera position and then used that position to compute a direction in “camera space’ to allow a ray SOP to project scattered points onto an object as a camera projection. Sounds complex, but it’s not. Here’s the wrangle which uses optransform and cracktransform to get the camera position:

vector @cdir;
vector @raydir;
matrix camMatrix = optransform(chs("camera"));
//get a matrix with the camera's transforms.
@cdir = cracktransform(0, 0, 0, {0,0,0}, camMatrix);
//extract out the camera position as a vector
@raydir = normalize(@P-@cdir);
//get a vector to project pointo from camera

This was fun and quick to do by restricting the direction particles could move to 45 degree increments and keeping them flat on the ground plane. Eventually I’ll be posting .hip files with these posts, once I get this blog’s back end a bit more up to date.

Here’s another super-simple trick you can perform with the dot product of two vectors. If you create two nulls and get the vector between them, you can compare that with the vector from any point to the first null using a dot product. Any value less than zero is past the plane of the first control normal to the second. That doesn’t read well, but the result is straightforward, you are using the controls to act like a normal and cull points.

Furthermore, the distance between those two nulls acts as a handy scale factor to color points in a gradient between the two. Here for instance we’ve “cut” a sphere in half…

The structure is very simple as you can see in the network view. The wrangle is also very simple. Thanks to Tokeru for inspiration and the basic structure of this wrangle.

vector p1, p2, v1, v2;
p1 = point(1,'P',0); //control null 1
p2 = point(2,'P',0); //control null 2
v1 = normalize(p2-p1);
//vector between control nulls
v2 = @P-p1;
//vector from current eval point to control 1
f@angle = dot(v2, v1);
//The dot product of the two, indicates 'perpendicularity'
if (@angle <= 0){
removepoint(0,@ptnum);}
//Cull out any points past p1
float dist = distance(p1,p2);
@Cd = dot(v2,v1)/dist;
//The distance between the two can also act as a gradient

This works, but there’s a far simpler approach to take using the matrix transforms mentioned a few posts earlier. Transform the points to the origin of a control object’s local space (you saved that wrangle as an asset, right?) and then you can use very simple logic – in this case let’s delete any point greater than zero in z.

if ( @P.z > 0) {
removepoint(0,@ptnum);
}

Translate the points back to their original world position (in that other wrangle you saved as an asset, right?) and bam, you have a super easy tool to cull points according to a control object. Or make a gradient, or whatever else you want.