Houdini - VEX Flex

This is not really VEX flexing but I really liked that title :)



In an Unreal shader I was building I needed to “rotate back” some pixels in the normal map so that the normals was corrected when the uv for the texture sampling was rotated. The key is to use the inverted rotation to rotate back the R(U) and G(V) color values (per pixel) so that the map is corrected. Here is a hip file demonstarting the concept:

Also a big gotcha for me was that when you generate the normal map for use in unreal it needs to have the Y flipped, if not the math would not work as intended.

Rotating a vector 2 and the inversing the rotation to cancel out the initial rotation

A naive solution that creates quad polygons from input curves. Note that the number of points per curve must be the same. Also they should have the same vertex order.
Run over: detail

int num_prims = nprimitives(0);
int i, j, pnt_0, pnt_1, pnt_2, pnt_3, prim_id;
vector p0, p1, p2, p3;
for(i=0; i<num_prims-1; i++){
        int pnts[] = primpoints(0, i);
        int pnts_next[] = primpoints(0, i+1);
        int num_pnts = len(pnts);
        int num_pnts_next = len(pnts_next);
        for(j=0; j<num_pnts-1; j++){
                p0 = point(0, 'P', pnts[j]);
                p1 = point(0, 'P', pnts[j+1]);
                p2 = point(0, 'P', pnts_next[j+1]);
                p3 = point(0, 'P', pnts_next[j]);
                pnt_0 = addpoint(0, p0);
                pnt_1 = addpoint(0, p1);
                pnt_2 = addpoint(0, p2);
                pnt_3 = addpoint(0, p3);
                setpointattrib(0, 'prim_id', pnt_0, i);
                setpointattrib(0, 'prim_id', pnt_1, i);
                setpointattrib(0, 'prim_id', pnt_2, i+1);
                setpointattrib(0, 'prim_id', pnt_3, i+1);
                int prim = addprim(0, 'poly', pnt_0, pnt_1, pnt_2, pnt_3);
                setprimgroup(0, 'new_quads', prim, 1);

Creates points that can be used as source to copy geo to. The poits are created on top of each other and the psacle is used to make each copy larger
Run over: detail

int num = chi('num');
float inc = 1.0/(num-1);
vector center = chi('use_center') ? chv('center') : {0,0,0};
vector rot_offset = chi('use_rot') ? chv('rot_offset') : {0,0,0};
vector4 orient = eulertoquaternion(radians(rot_offset), XFORM_XYZ);
for(int i=0; i<num; i++){
        float pscale = fit01(chramp('scale', i*inc), chf('scale_min'), chf('scale_max'))*chf('scale_mult');
        int pnt = addpoint(0, center);
        setpointattrib(0, 'pscale', pnt, pscale);
        setpointattrib(0, 'orient', pnt, orient);


Creates pscale attr along input polylines using a ramp
Run over: primitives

int pnts[] = primpoints(0, @primnum);
int num = len(pnts);
int i;
float inc = 1.0/(num-1);
for(i=0; i<num; i++){
        float pscale = fit01(chramp('pscale', inc*i), chf('pscale_min'), chf('pscale_max'))*chf('pscale_mult');
        setpointattrib(0, 'pscale', pnts[i], pscale);