Wednesday 27 November 2019

adding noise/field effects in certain areas

Lifted from the Houdini help page.. Useful for localised noise/breakup

You can attach DOP nodes that modify velocity fields, such as Gas Turbulence, to the fourth ("Advection") input of the Pyro solver node. Most field-modifying nodes have some way to scale the effect by a mask field.
Create a geometry object in the shape of the area you want to affect.

Convert geometry to a fog volume - use an isooffset

In the DOP network, add a SOP Scalar Field node after the Pyro object.
  • Turn on Use SOP Dimensions.
  • Set the SOP path to the path of the fog volume object (for example /obj/mask_object). Make sure Use Object Transform is on.
  • Set the Data Name to something indicating the purpose of this field, for example NoiseMask.
This attaches the fog volume as field data on the Pyro object with the given name.

Create a Gas Turbulence node and connect it to the fourth ("Advection") input of the Pyro solver.


  • On the Bindings tab, set the Density Field to the name of the mask data, for example NoiseMask. The effect of the node is multiplied by the value of this field.
  • Use the controls on the Turbulence Settings tab to control the amount of turbulence added.

Wednesday 30 October 2019

camera projection with houdini

Houdini camera projection is as simple as creating a "UV TEXTURE" node and plugging it into the geo you're projecting onto.
In this node, select "Perspective from Camera", from the Texture Type dropdown menu.
You could name the UV Attribute something other than the default of "uv" if you are creating some alternate uv sets.
In the Camera dialog box, specify the camera node. Eg. /obj/cam1 & usually the attribute class for the uv's will be set to vertex.

Now, whatever material you apply to it will use these uv's. (or maybe a different set if you specify within the shader network!) eg. uv2.

Friday 25 October 2019

size of array, VEX snippet

i@size=len(i[]@nameOfArray);

the [] is actually [   ].

activating particles

to have particles come alive, mid sim (or indeed, to have them stop mid sim) you just need to trigger the "stopped" attribute in your pop network.

blurring vdbs

float dist = xyzdist(1,@P);

float distremap = fit(dist,ch("near"),ch("far"),0,1);

f@density *= distremap;


This gives a vdb a falloff based on how close it is to the original object's surface.
Stick the VDB into a volume visualisation and then plug that into input 0
Put the original geo into input 2.

Now you can "blur"

Saturday 19 October 2019

group centroids

group centre/centroid - intstead of blasting out groups and using $CEX etc, you can just use $GCX, $GCY, $GCZ in your transform pivots.

Wednesday 2 October 2019

Selection expand

To expand - any - selection like in Maya... do your selecting then press SHIFT G (to grow) or SHIFT S (to shrink)

Friday 6 September 2019

seperated AOVs eg(z depth at 32 bit)

Half precision and 32 bit for z depth 
16 bit half precision but utility passes in 32 bit. 

- on your AOV, tick Separate File
- set the filepath to the same location as your beauty render but with the name of the pass suffixed, e.g. for the Z depth it might be: _$HIP/../../render/$OS/$HIPNAME/`$OS`_Z.$F4.exr_
- set Precision to 'Float 32 bit'

Tuesday 3 September 2019

rotating point normals, with vops

To rotate a point's normals (or any vector for that matter) you need to multiply it with a matrix and an angle (usually in radians) and around a specified axis.

A much neater/easier-to-grasp method is to use a VOP.
Give your points some initial Normal values, eg point them in X.

Make a point VOP.
Connect the N output into a multiply. We want to multiply this N vector and get a vector output.
The output of the multiply should go to the N output.

Make a DegToRad node (skip if you speak radians) and connect that to the angle input of a Rotate node. Promote the DegToRad's angle input so you can tweak it at object level.

In the Rotate node, set the vector that you wish to spin the normal vector around. It might be Y. 0,1,0.
Or you could be doing something  cool like calculating the vector that an edge lies on and spinning something around that.

Connect the output of the Rotate to the second input of the Multiply.

Now jump back out of the VOP and you should be able to see your normals rotating when you change the angle input.

-------------------------------------------------------

Of course this is just a couple, maybe one, of lines in VEX, but who really has time to memorise that? heh.

Monday 2 September 2019

Checking if your instancefile files exist

Checking if your instancefile files actually exist...Cos sometimes...they don't! Stolen from MikeB

Paste this into a Python node:



import os

node = hou.pwd()
geo = node.geometry()

geo.addAttrib(hou.attribType.Point,'exists',0)

for pt in geo.points():
    file = pt.attribValue('instancefile')
   
    if os.path.isfile(file):
        pt.setAttribValue('exists',1)
    else:
        pt.setAttribValue('exists',0)
   

Friday 23 August 2019

wedging

BASIC WEDGING (nothing fancy here. Might do something more detailed later)

For when you want to vary the parameters in something and render them all out.
Eg. Caching out a sphere with different scales

In that nice boring case, you need a couple of things in your ROP area.

1.
A Geometry ROP, point the SOP path to your sphere's output
Set the Output file to something like
$HIP/geo/sphere_`$WEDGENUM`_whatever.bgeo


2.
A Wedge node
Point the Output Driver to the Geometry ROP. This shouldn't be necessary, as you can just wire the Geo ROP into the Wedge, but when using plugins such as Deadline, sometimes it doesn't know to take that input....
Let's not do random samples, so untick that.
Add a Wedge Parameter by pressing the + button, give it a name...in our case, we'll call it Radius
Type in the path for the channel we're wedging in the Channel box
eg. /obj/geo1/sphere1/scale
Set the range of values you want. Eg. 1 to 10
Set the number of steps to take - Houdini will do uniform divisions, so in our case we should get scales of 1-10 if we type 10 steps.


3.
Hit Render Wedges. Or plug your wedge rop into Deadline and submit it as normal.


NOTE -
I sometimes use a NULL in my SOP as a controller for certain things. It can be easier to wedge the channels on this null and then copy the relative values into other nodes, so everything is easily accessible.





Friday 9 August 2019

padzero to do file names!

/tba/CLIENT_JOBS/GREY_LDN_Zalando_Dont_Change_100713/vfx/shots/sh0033/houdini/sourceimages/backplate/backplate_guide.`padzero(3,$F3-1000)`.jpg


padzero(number of zeros, thing you want to pad) turns _guide.2.jpg into _guide.002.jpg

Monday 24 June 2019

FETCH inverting transforms at object level

Recently I transformed a camera (scaled and rotated) to make things easier to work with in Houdini.
I did this with nulls at object level, rather than within the SOP themselves.
However, when transferring my assets back to Maya there was no clear way to invert the transformation (like in the SOP level Transform nodes).

The answer to this, is to use a FETCH node (thanks Matt Evans), which I pointed toward my rotation null and I told it to invert.. This Fetch node was then plugged into the geometry I was trying to return to the original camera orientation/scale (as you would with a null).

basically!
SCALE NULL--->ROTATE NULL--->CAMERA

FETCH(points to ROTATE NULL,with invert ticked on)--->GEO


Wednesday 19 June 2019

rotate packed primitives/ WALTER ROTATE

how to rotate a/bunch of packed primitive/s -
Use a WALTER ROTATE.

in a primitive wrangle:


float randomFactor=rand(@primnum+2323)*chf("randomMult");
matrix3 rot = primintrinsic(0, "transform", @primnum);
vector4 orient = quaternion(rot);
vector x = normalize(qrotate(orient, {1,0,0}));
vector y = normalize(qrotate(orient, {0,1,0}));
rotate(rot, radians(chf("angle") * randomFactor), x);
rotate(rot, radians(chf("angley")), y);
setprimintrinsic(0, "transform", @primnum, rot);

//////////////////
what we are doing is:
  • making a random factor to multiply the rotations, using primnum as a seed
  • creating a matrix called "rot", and initialising it to the transform of the primitive
  • create a vector called "orient", using the quarternion of the rot matrix
  • create vectors x and y
  • rotate the rot matrix using input angles for x and y
  • then finally set the primitive intrinsic using the rot matrix

Friday 31 May 2019

vellum hair thickness

To randomise vellum hair thickness, you use pscale values. To get Vellum to recognise these values, UNTICK the Thickness box in the Vellum Constraints node.

polywire radius

To vary the thickness of your polywires, simply type in the @variable you've made into the "wire radius" field of  the polywire node.. A rather simple thing that I should have figured out *facepalm*.

Tuesday 28 May 2019

spinning particles/points/rbds

I made a previous post about spinning particles with "w" and Pop Torque.... Walter uses this & it seems much simpler (?). In your DOP network, create a Pop Spin node & in the VEXpression space type:

spinspeed = 100*(fit01(rand(@id),chf("min"),chf("max")));
axis = sample_direction_uniform(rand(@id));


Spinspeed is measured in degrees per second
Axis specifies the axis of each point you're spinning. The sample_direction_uniform() function returns a normalised vector. So here, we have a completely randomised rotation axis. Not bad.

Tuesday 30 April 2019

recalculating velocity

Nicked from Walter..

Velocity is a vector..
Velocity=speed x direction.
I was using this because some of my POPs had too much speed and were going through my collision objects.

If you store the normalised version of your velocity, this is the direction. Then you can multiply it by a new speed.. Perhaps you want to make it 85% of it's velocity until it reaches your max target?

So...in VEX:


vector direction=normalize(@v);

float speed=length(@v);

if(speed>chf("maxSpeed")){

speed*=chf("dampMultiplier");
}


Friday 19 April 2019

Group selection expand.

If you need to expand your group's point selection, make ANOTHER group node straight after it.
Specify the same name and change it to Point type (this only works with points I think).
Set the Initial Merge to Union with Existing.

Untick Base Group.
Tick "Include by Edges" and also "Edge Depth".
Specify the group name in the Point Group box and drag the slider to see your point selection increase.

If you want to put the expanded selection into a new group, give it a different name at the top. 

Thursday 18 April 2019

PYRO DIY 2019

The pyro setup tools have changed a little bit in Houdini 17..

Here's a refreshed outline of what you need to make a setup from scratch.

  1. Create something to emit the pyro. You'll eventually be turning it into a volume, so keep that in mind.
  2. Plug your emitter object/points into a Pyro Source node. 
  3. Optional, but usually a good idea - Connect an attribute randomise node and randomise Density and Temperature
  4. Use a Point Wrangle to randomise pscale with your favourite function (or don't)
  5. Connect a Volume Rasterise Attribute node and specify  Density, Temperature and V (for velocity) as the things you want to rasterise. Now you have some volumes which will act nicely as sources for smoke. Label them with nulls (SOURCE)
  6. Before we jump into simulating, there are two more things we need to make to help along things. A box that encompasses the volume of the entire sim and a box that roughly covers the volume of the first frame of your sim. Label them with nulls( BOUND and START for example)
  7. Create a dopnetwork. Inside, make a Pyro Solver. This is the brains of it all.
  8. The first input into the solver should be a Smoke Object. For testing purposes use a higher division size, maybe 0.1, which represents 10cm as a single voxel. In the "size" boxes, use an expression bbox("../../START",D_XSIZE) and respectively the D_YSIZE, D_ZSIZE 
  9. For the centre, use the expression centroid("../../START", D_X) and D_Y, D_Z
  10. The rest of the Properties tab can usually be left as default.
  11. In the Creation tab, set the Creation Frame to the first frame where your source appears. You may or may not want to have Solve on Creation Frame ticked on. See what works for you.

  12. The second input into the solver is the Gas Resize Fluid Dynamic.
  13. The Max Bounds tab is what we're interested in first. Set the type to "From Object" and navigate to the BOUND object you created in step 6. This stops the simulation from going nuts and out of bounds.
  14. Back in the Bounds tab, you might have to play around with the padding values. Generally the closer to zero, the less extra work the solver has to do.
  15. Let's skip a few inputs of the solver. The last input will be the source volumes. Add a Volume Source node and navigate to your SOURCE object (step 5) You could have this connected to the Dopnetwork as one of the inputs, but lately I tend to keep those clear (you might have many sources etc..)
  16. In the Volume tab, press the + button. You'll want to add the "density", "temperature" and "v" from your SOURCE. Label the target fields "density", "temperature" and "vel" respectively. The first two are scalar values & vel is a vector one.You could leave out temperature and velocity if your sim doesn't really require it, but I find a little bit of temperature helps gets the sim moving.
  17. Hit play, or click on a frame (this is faster, as having to display each frame slows down Houdini a little) in the timeline & wait a little bit. Something should have happened!

  18. The sim probably looks a little simple. We can disturb the velocity or temperature to make it look more interesting now. This is what the third input is for. You can plug in Gas Disturbance, Gas Turbulence and a few other nodes to do the trick here.
AND THAT'S IT.. A simple and clean pyro setup.

Copying different objects to points

Sometimes you need to copy a bunch of different objects to points. Eg. You have 5 variations of wood splinters and you're emitting them from a snapping plank.
Instead of using the slower copy stamp with random point values, you can use a ForEach loop and a Switch node..and of course a point wrangle.

Connect the objects to the Switch node. In a point wrangle, give each point an (random) integer value (eg "instanceID") ranging from 0 to the number of objects you have.
Make a ForEach network and connect the Point wrangle into the top. Create a null node directly after the start of the Foreach Begin. This will be a "temporary holder" node. It will carry the instanceID value to the Switch node. I've called it PT
The clever bit happens in the Switch node. In the parameter window, click on the cog wheel and add a Spare Input. This will create a new dialog box called Spare Input 0. Type in:

../PT

This will point the spare input to our temporary null & its instanceID value.
In the Select Input dialog box, type

point(-1, 0, "instanceID", 0)

here we are telling the Switch node to get a point attribute from input -1 (which is the spare dialog....which is pointing to the PT temporary null..). The attribute in question is instanceID.. NICE.
A purple arrow going from PT to Switch should have appeared now. This represents that link we've just made.

All that is left to do is to create a Copy To Points node & put the Switch output into the objects input & plug PT into the points input. Finally plug the output of all of that into the Foreach End.

Tuesday 16 April 2019

Check names for duplicates

point wrangle snippet from Mike

int find = findattribval(0,"point","name",s@name);
int count = findattribvalcount(0,"point","name",s@name);
i@find = find;
i@count = count;

Friday 12 April 2019

solver sop and moving geometry

So, the Solver SOP doesn't behave as "I" expected with animated (ie. moving) points/geo.

You need to manually update the position if you want your geo to still move!
SOOOOOOOOOO. Inside the solver, copy the P (for position) attribute from Input 1 to Prev Frame...

Weird stuff. But hey.

removing RBD from a sim

Sometimes you need to remove an RBD from a sim completely. Eg, you're using a block to push something and then need it to get out of the way...

Make sure you have a group for it on SOP level. It will probably be a point group, as you're most likely using packed geo.

Now use a SOP solver in your DOP network. Attach it to a multisolver, alongside your Bullet/RBD solver..
Inside the SOP solver, blast the group that you created earlier. Use a switch node or some other timing device (you could use a point wrangle with removepoint I think)  to trigger the group's deletion.
Eg. Switch node  could use $F>1000. Here it will switch from "all the geo" to "all the geo minus the group" input.

Select a random point from a group each frame

Some code snippets from Walter to use points from a group randomly, for emission (or other things)

In a Detail Attribute Wrangle-

int npts = npoints(0);
float keep = rand(@Time + 235.624) * npts;
i@keep = int(keep);

Every time step, a random point id is chosen as the "keep" point.

Then in a blast, we kill everything but the kept point

`detail(0, "keep", 0)`

Don't forget to invert the blast selection

Saturday 6 April 2019

Bullets solver, setting or changing attributes

Bullet solver is a bit strange in Houdini. It might not update values as you expect. Eg, you're trying to change the @active value using a sop-solver.
One solution is to use the Bullet mode in the RBD Solver. This usually works..But it might be slower? I think it has a multi solver built into it..

Another way to make it work is by utilising a multi solver and the Geometry Wrangle. This will let you access the SOP level stuff (there is an input tab you can mess around with)

So, your input RBD goes into the first input of the multi solver, then your Bullet Solver and any Geo Wrangles go into the purple input of the multi solver..

Friday 5 April 2019

Wednesday 3 April 2019

match, finding a string in a wrangle. Wildcards.

in Blast nodes you can use wildcards * all over the place
eg. @name=*something
will kill anything with "something" in it's name attribute. It's a little different when you want to select things in this manner in a wrangle. We use the "match" function to do this-


if(match("*stick*",@name)){

s@value="yeah!";


}

Here we look for the string "stick" in the attribute "name". On success, we make "value" equal to "yeah!".

Tuesday 2 April 2019

separating objects for booleans/other things

Case example - you have a 


To separate out an object, maybe for booleaning, or to avoid intersections when doing some other sort of calculation, make a point class attribute (connectivity)
then in a point wrangle do something like this-

@P.x+=@class;
@P.y+=@class;

This should separate the pieces enough. If not, use a multiplier.
Then promote the class to a primitive attribute - for some reason Boolean Fracture doesn't carry across the class attr to any newly generated points when it is left as a point attr.


Do your booleans...you might want to scatter some points on the surfaces or copy some turbulent grids onto the object points.

Bring the class attribute back to point level and then do the reverse transformation

@P.x-=@class;
@P.y-=@class

 link any multipliers you might have to save time changing values in multiple boxes!



Saturday 30 March 2019

constraints between two different objects refresh redux ultra

I've probably made a post about this before. Or I thought I did. .. anyway. I only make notes about things as I actually do them :) Repetition is the key to learning !

If you're trying to create constraints between two different objects, say a bunch of bricks and a big big of plaster wall you have to approach your primitive constraints generation a little differently than usual.
Normally you would put a Connect Adjacent Pieces node down and this would draw lines between your closest points. However if you were to merge the bricks and plaster together and do this, you still end up with lines being generated between brick bits and plaster bits..when all you actually want are the lines exclusively between brick & plaster. Whew.

To achieve this you have to hijack the name attribute of your brick and plaster geometry so that Houdini thinks there are only two names to connect between. Instead of having "brick01,brick02,brick03,plaster01,plaster02,plaster03" you will have "brick,plaster". that's it.
In a Point Wrangle(for packed geo) or a Primitive Wrangle(if you are working with unpacked geo) for each of your objects do something like this -

s@original_name=@name;
s@name="objectA";

where objectA might be "brick", object B might be "plaster". Now merge these two mono-named objects together , promote the name  attribute to point level (if it isn't already) and apply the Connect Adjacent Pieces node to them. Now you should only see lines being generated between the two seperate groups of objects. Brick to Plaster. Plaster to Brick.
Finally you must bring back your original name, so use an attribute rename node for this..


Plug your nice sparkly constraints into the rest of your network!


Friday 29 March 2019

2d zoom pan

ctrl alt rmb drag..
if there's an image plane, lock the camera movement

RBD Hard Constraints/Glue Constraints & Sanity check

hard constraints will read Force, Angle, Torque and Distance
Glue constraints will read Strength and Impact

Sometimes you will glue things together and they will still seem to come apart (when attached to something animated for example). Try solving the RBD Packed Object on creation frame - this MIGHT fix it...

Check your Constraint Network's "Overwrite with SOP" field if constraints are not being deleted correctly. It should only be active (value of 1) for the first frame of the simulation. Then it should go back to 0. Otherwise, it will constantly read in the constraints from the SOP level (ie. replacing it with vanilla untouched constraints)

Wednesday 20 March 2019

RBD Clustering, an "update"

Instead of using the cluster attribute found in Sam's notes...

Add a primitve VOP to your constraint primitives.
Create a voronoi noise and promote the frequency to the top level.
Plug the output (dist1 is good) into a ramp float node and then mess around with the curve to create some interesting patterns (try adding noise to this), which will essentially operate as clusters.. Export this to Strength, or multiply it by a pre-existing value.

Friday 8 March 2019

RBD, Constraints..Glue, fracturing. NAMES

Name attributes are the most important things when making constraints for RBDs.

Create a name attribute for your object/fractured pieces by laying down an Assemble node, without the Packed option enabled. Create your constraints with this geo (it will retain the Primitive Name Attribute, and pass it down to the Point level once you've used Connect Adjacent Pieces)

In another branch, use another Assemble node to follow up the previous Assemble node, this time with Packed enabled, but the others disabled. Now when you add your constraints to your DOP network, they'll be able to find the correct Pieces to attach to.

ALSO make sure your object names are all unique.
Names. Names. Names.

Another "quick" way to make rest lengths for your constraints is to do a Convert Line node just before the Primitive Wrangle (where you do s@constraint_name="thingy"). This is important for Hard Constraints.


A general rule for constraint types - Hard Constraints will provide overall flex between pieces.. Glue Constraints will keep the pieces all together.
Hard Constraints react to Force, Glue Constraints DO NOT.
Glue Constraints react to Strength and Impact. Hard Constraints DO NOT. *

*unless you tell them to in a SOP Solver - eg. if (@force>chf("breakThreshold")*@strength)
But this is you explicitly adding Strength into the mix... Could be any old attribute.

Wednesday 6 March 2019

point deform tricks

The point deform node is very useful to wrap deform high res geo with lower proxy geo.
To help it along in the case of overlapping objects, you can offset the objects.
Create a  point class attribute for both the high res and proxies.
Then move the pieces both high res and rest-position low-res using @P+=i@class
The deforming proxy geo will stay "as-is".

By seperating the geo in this way you can avoid "some" intersections...


Monday 14 January 2019

set animation curves to infinite, etc.

In the graph editor, right click the channel (eg. translate Y) and click Channels>Channel properties..
Here you can change the In and Out to whichever infinity-behaviour you'd like.

stick noise to geo

Something super simple and dumb that I'm surprised I've never used beforehand!

To keep a 3d noise value from,say, a point-vop sticking to Geometry, make a rest-position value before the object is meant to start animating. There is a handy Rest SOP for this.