Houdini Particles and PCopen
A primer on how to use PCopen in VOPs to advect particles (or modify just about any geometry attribute on a point, grid or shading sample). While POPs has changed a lot since 2009 this article will still help you grasp the relevant workflows.
Point clouds are one of those things in Houdini that can be confusing and unclear the first time you try to use them; people often throw the term about in many different contexts and the documentation doesn't make it clear what's going on either. So I figure I should write up some common workflows and how they might apply to the POPs context.
First up is using the pcopen pop vop, and how it can pull arbitrary float or vector attributes off geometry. It's kind of like an attribute transfer sop or pop, but done within a pop vop context so you can link it directly in to whatever you are cooking up. The cool thing is that you can directly reference another sop that is cooked dynamically as per normal- no caching required! (though you can cache stuff to disk if you like). This is particularly handy if you are super-sampling the particle system (sampling the sop and pop chain more than once per frame).
So put down a source pop, emit some stuff and add a vop pop. Set up the network like this:
Important! In order to open the current SOP geometry in the pcopen, you need to add this to the file input path that will be created on the vop pop: op:/obj/geo1/OUT_sopobject
You'll see the particles move up off the source, and as they fall within the search radius of the pcopen the vop pop will grab up to 10 of the nearest points off OUT_sopobject and pass them to pcfilter- which will average the vector values. The resultant vector is simply added to the particle's velocity and it will therefore fly away. Here is the .hip: pclouds_basicNormals.hip
So that's an example using normals- but lets throw a sphere through some stationary particles and cause it to push them away via it's velocity vectors. Animate a sphere moving, put a trail sop after it and set it to calculate the velocity vector. Emit some particles that will be in the way, just scattered over a grid will do. Copy and paste the above vopnet and watch it do it's thing:
So it works, and it's pretty fast. You can now push particles around with the velocity vector, in fact colour (Cd) is a vector too so you could change that with a pcopen, or an arbitrary vector or float. Anything you like you can open via the op: tag.
As you can see, as a point comes into the range of PCopen it will just grab the velocity/normal off it and add it straight onto velocity. This works, but it's not aesthetically pleasing as there is no distance blend or falloff- also, adding it straight to velocity can cause problems later which I'll get into. So, here is how to rig up a ramp to blend over the distance from the point that is opened, and the particle the vop pop is dealing with at that time:
The way this works is that there is now another pcfilter attached to the pcopen- this one opens P, the averaged position vector of the points being looked up. So to get the distance there just subtract one from the other, and get the length of that vector. To use the lookup ramp (rampparm1) you need to give it a normalised float input; ie a value of between 0 and 1 where 0 is a very small distance, and 1 is right at the edge of the lookup radius max. So we use a fit to re-assign/calc the distance value. Then use a velocity multiplier to globally adjust how much to add, and add the resultant vector to vel. You can now use a nice lookup ramp to graphically control the responsiveness that a particle will have to the looked-up Normal vector depending on distance.
So far we have been adding a vector directly to velocity, but this comes with a number of problems. Pops is essentially a big loop, and if you continually add a vector to vel then things rapidly diverge and explode- this is particularly true if you turn oversampling up. Give it a go and you will see that the particles fly away from the surface twice as quickly, this is because the popnet and it's sop inputs are being cooked twice per frame (if you set it oversampling to 2). One way to do this would be to simply divide the vector you are adding to vel by a scalar amount directly linked to oversampling, which will more or less preserve the nature of the pop sim and keep things predictable.
Another simple way to advect particles would be with a mix node where every time the vop pop is run, it will mix the current velocity say, 50% towards the new sampled vel. This is quite easy and can look good, but sometimes overrides the natural motion of particles. Also note that if there is nothing within the pcopen radius, pcopen will return 0- so you will be mixing a value of nothing into your vel and your particles will freeze! You should nest the advection in an if(vel>0) loop or switch to get around this.
OR, you could just add it to acceleration (accel on the output).
OR, you could do some dodgy vector maths and subtract the current vel from the pcopen vel, then add the result onto current vel (with any scaling multipliers).
If you come up with a funky way to blend in the new sampled vel, let me know and I'll add it in here. I'll probably add more to this later, but for now it should get you going with pointclouds and POPs. RE rendering and pointclouds- you can actually do a PCopen in a SHOP VOP, and do the same stuff in VOPs as I explained above; but this time in the context of generating a value for rendering- but I will get to that later.