NokiMo
naelstrof
naelstrof

patreon


Procedural Fluid Streams

The next thing on my block of VFX work to tackle is a water stream from a hose. I might over-explain my thought process but I'm pretty excited about it so sorry in advanced!

This post will be public since it's one of the few posts I can make public. Hope you all like it!

I've already got a flask with a spray nozzle, and I just needed to break down how the nozzle effect might play out.

So the first thing to note is that the stream has a parabolic curve. This can be achieved in a couple ways, I was thinking maybe I could simulate some physical particles and use bones to attach the points together.

So I whipped up a tube and weight painted it the best I could and...

Ugh.. Gross. After messing with it quite a bit, it was painfully obvious that it wouldn't be able to deform very well. Not to mention that it'd be fixed to a certain number of segments/particles.

So instead, I thought about maybe just mathematically defining the curve of the stream with physics, then deforming a cylinder to that path.

Using the projectile physics formulas `h = vt+gt^2` and `x = vt` (Thanks high-school physics!) I could offset a really dense cylinder like this onto the curve using a vertex shader.

Here's my first attempt. I take the object forward direction and use that as the "x" direction. And I use the world down direction for gravity (h in the functions earlier).

Woo! Kinda like a stream. Now there's an issue with the rotation of each disk in the cylinder being incorrect. Though this can be easily calculated with Calculus!

I get the slope by deriving each function with respect to time. `h'=v+2at` and `x'=v`. (Thanks high-school Calculus) I use that to determine how to rotate each disk to match the curve.

Woo! Perfect parabolic cylinder.

Slap some deformation scrollers on there.

Sick. 

Now I wanted to make it more physical, so it seems like a real physical projectile. To do so I added a tail twist and translation. And I use a script to feed in the delta rotations and delta positions of the object its attached too.

At first I accidentally used degrees when the function was expecting radians. Which led to this beautiful mess:

 https://twitter.com/naelstrof/status/1183688426828099584?s=20 

After fixing that, I added a clipping variable that lets it "shoot out".

Woo! Now it kinda looks like a real stream in the world.

Final thing I need to do is to actually ray-trace it and spawn some particles. Since the path is strictly determined, it's really easy to replicate the shader path in code.

I split up the raycasts into segments and make it follow the curve. If it hits something it updates the culling shader variable so the stream "hits".

Final step is some particles!

Woo! Water!! Check the next post for a video of the completed effect.

Comments

Juicy!

Ryagon


Related Creators