Below you will find pages that utilize the taxonomy term “vex”
Posts
Vectors - Double Cross Product
We start with two vectors @N (yellow) – which is the primitive’s normal from a Normals SOP, and {0,1,0} – the global up (gray). When the primitive is not rotated, these two vectors are parallel.
By using a buncha cross, we can derive our main axes:
vector pink = cross(@N, {0, 1, 0}); // First cross product vector green = cross(pink, @N); // Second cross product, the "double cross" Note 1: The green vector is essentially an “up-ish” vector that is always parallel to the plane and never points downwards.
Posts
Houdini - Rotations and Look At
A point doesn’t “point” anywhere. Points have no implicit direction or orientation. The idea of “rotating a point” is essentially meaningless.
1. When we “rotate a point”, we are implicitly saying “translate this point around the origin”. Take this example of “rotating” points in a Point Wrangle:
matrix3 m = ident(); rotate(m, @Time, {0, 1, 0}); // Rotate on Y over @Time @P *= m; What we’re really doing is translating points around the origin:
Posts
Houdini VEX - Distance and Neighbours
1. The “workhorse” functions Most of the time, we use these to query distance: distance, xyzdist.
2. Query from a single point/prim When you ask: “Who’s next to me? Who’s nearby? Who’s connected to me?”. We ask this when we need to do stuff like growth propagation: nearpoint(s), neighbour(s), polyneighbours.
3. Specialized Other functions/operators that work with distance: surfacedist, pcfind, minpos, Find Shortest Path, Distance From Geometry
1a. distance An infrared ramp is used to color points based on their respective distances to the orbiting ball.
Posts
Vectors - Positions and Rotations
An arbitrary point in space (x,y,z) is a vector <x,y,z> from the origin. Adding a vector <a,b,c> to a point gives us another point. The vector <a,b,c> can be derived by subtracting P1 from P2. So far:
vector abc = {1, 2, 3}; vector P2 = P1 + abc; vector def = P2 - P1; // def == abc The vector <a,b,c> defines a line in space between P1 and P2.
Posts
Houdini VEX - Bias Lerp and Slerp
A bias value tells us where, along an interpolation, to grab a value from.
If we’re interpolating between the numbers 1 and 2, when bias == 0, the return value is 1. When bias == 1, the return value is 2. Thusly, bias == 0.5 would return 1.5.
There are two main functions to get this “return value”: lerp (for all numbers and vectors) and slerp (for quarternions).
Formally, to get the “middle” of interpolating between 1 and 2 (above example), we would write:
Posts
Houdini VEX - Noise and Curves
In these examples, we have a line along +x and we use noise functions to distort it along the y-axis.
Inside a Wrangle over points:
float offset = 0; // This is zero for simplicity @P.y = sin(@P * @Time + offset); The combined term of @P * @Time is the frequency of the curves. The higher this number – as @Time increases – the greater the frequency.
We start with the simplest, using sin:
Posts
Houdini VEX - Random Directed Vectors
This is a great way of getting “random” vectors but you need the vectors to be “clamped” to a certain range of “spread”.
To illustrate this, we’ll use a buncha points on a grid and “shoot” (aka move) them out “randomly” using sample functions.
1. Sample Direction Uniform vector2 u = rand(@ptnum); @P = sample_direction_uniform(u); Which gets us, well, a buncha points scattered in every direction.
2. Sample Hemisphere This function takes a center and a bias.
Posts
Houdini - Multiplying Quaternions
From this exercise and the following lines:
vector4 o = dihedral({0, 0, 1}, @P); // align z-axis with @P vector We get this result:
Now we want to face her ass out, which means we gotta rotate her 90-degrees on her y-axis.
From this exercise, we learned how to build a quarternion from a rotation and an axis.
vector4 r = quaternion(set(0, radians(90), 0)); // e.g {0, 90, 0} - rotate y 90-deg We combine both the rotations by multiplying the quarternions, using qmultiply:
Posts
Houdini - Orientation
How Houdini determines orientation Houdini searches for these attributes, in this order. It goes down this list until none is found.
@orient attribute. Use this to orient copy/instances. Using @N as the Z-axis and +Y is up. Use @v e.g. velocity. If @rot exists, apply it to the above. Copy to Points We have a point with @N = {0, 1, 0} e.g. its normal pointing up (the yellow trail).
Posts
Houdini - Quaternions From Rotation and Axis
float deg = radians(@Frame % 360); @orient = quaternion(set(deg, 0, 0)); Substituting set(0, deg, 0) - Y-axis.
Substituting set(0, 0, deg) - Z-axis.
Posts
Houdini - Selecting Points on a Grid
Using neighbourcount in a Group Expression operator to get points on the outer edge of a grid:
neighbourcount(0, @ptnum) <= 3 To get only the corners:
neighbourcount(0, @ptnum) == 2
Posts
Houdini - Selecting With Bounding Box
Use the relbbox function in a Group Expression to select points at the “extremities” of a geo’s bounding box.
E.g. the “front facing” points here are +1 on the z-axis:
relbbox(0, @P).z == 1 And the “back facing” ones would be z == 0.
The “top” points are +1 on the y-axis:
relbbox(0, @P).y == 1 Using the same expression lets us also conveniently select the “topmost” point on a sphere:
Posts
Houdini VEX - Attributes Inside VOPs
Inside a VOP node, an attribute is dubiously called a bound variable. We read/write attributes inside a VOP with the bind operator.
bind1 reads an attribute from outside the VOP called one.
bind2 creates an attribute and exports it outside.
The end result of this DAG is a red object!
Posts
Houdini VEX - Looping
A few variables are available for referencing in a Wrangle:
@ptnum – current point number up to @numpt @elemnum – current index of this element up to @numelem Their equivalents are @primnum, @numprim etc.
To loop over every point:
vector positions[] = {}; for (int i = 0; i < @numpt; i++) { vector p = point(geoself(), "P", i); push( positions, p); } Using foreach:
foreach(vector position; positions) { // Do something; }
Posts
Houdini VEX Attributes
Reading Attributes To access a point’s attributes:
@Cd = point(0, "Cd", @ptnum) // 0 is the input, or use 'geoself()' You can access point , prim , vertex, etc. See here.
Remember that inputs are zero-indexed.
To explicitly cast anything in VEX, use set.
float aFloat = 1.0; int cols = set(aFloat); // cast 'float' to 'int' int cols = (int)aFloat; // another way Setting Attributes To set an attribute:
Posts
Houdini VEX Groups
When you group stuff together with a Group SOP, Houdini simply creates an attribute called @group_{name} whose value is 1 or 0.
So to manually add an element to a group, just create the attribute on the element:
i@group_fuckheads = 1; // Remember to declare i! When acting on a point or prim from a detail:
setpointgroup(0, "selected", ptnum, 1); To check whether an element is in a group, just check for the attribute:
Posts
Houdini VEX Types
Type Syntax float f@name int i@name string s@name vector v@name vector2 u@name vector4 p@name matrix2 2@name matrix3 3@name matrix (4x4) 4@name integer array i[]@name vector array v[]@name string array s[]@name Declaring just a plain vector:
vector scale = {1,2,3}; A vector array: