Combine Normal and Orient Attribute for Copy To Points
31 Mar 26 (Today)
If you've ever tried scattering objects like grass or trees in Houdini, you've probably run into this frustrating issue: you use the normal (@N) attribute to perfectly align your grass to the terrain, but the moment you introduce an @orient attribute to add some random rotation, your normal alignment completely breaks.
Why does this happen? It comes down to Houdini’s instancing hierarchy. When the Copy to Points SOP evaluates your attributes, the quaternion @orient will always completely override vector attributes like @N and @up.
Fortunately, the fix is straightforward. Instead of letting them fight, you just need to mathematically stack them using a quick VEX snippet.
The VEX Solution
To combine these rotations, drop down an Attribute Wrangle right before your Copy to Points SOP. Connect your scatter points to the first input and paste this in:
// 1. Define your geometry's default up vector.
// (Assuming your grass points straight up the Y-axis)
vector default_dir = {0, 1, 0};
// 2. Create a quaternion that aligns the default direction to the terrain's Normal.
vector4 normal_orient = dihedral(default_dir, @N);
// 3. Multiply your existing @orient by the new normal_orient.
@orient = qmultiply(@orient, normal_orient);