Wednesday, 15 April 2020

Rain Shader Part 2 - Moving Drops

This is the continuation of the procedural Rain Shader. After finishing the static drops I of course needed some that run down vertical surfaces. Since the initial setup is very similar I will skip explaining some of the first steps and jump straight into the more exciting stuff.

I looked for some reference video clips and found this one. There are some things, like merging raindrops or the trails, which I won't be able to recreate, but it helps to give me a general idea of what I am looking to achieve.


Before going into explaining further steps, my current state of the Material Function looks like this.
The UVs are not quadratic anymore, I set it to a different ratio, so I have more vertical space for the drops to run down. I have generated random offset values for. Since the XY-Position will be animated the method for offsetting is a bit more complicated.

Basic setup
The next step I wanted to work on was having the drops move down. The easiest way of achieving this is by just using a panner of offsetting the UVs over time. This however makes the drops all move at a constant rate, which looks very unnatural, since rain drops usually move with varying speed due to surface properties, etc.

Triplanar Mapping with Panner
Since I cannot change the position of the UVs for each individual drop I need to change the Center position of the drop by using another function. This can counteract the UV panning so that the drop sometimes seemingly moves faster or slower. The easiest solution, even though not the most elegant, since it is still a very uniform funtion, is using sine. After setting it up it looks something like this:


Not quite what I was looking for. I am going to dive a bit more into the math behind it to explain how it works.
Let's assume we have a time frame of 1 second. We know that the UVs travel a distance equivalent to the speed. In a function it can be described as distance = time * speed, where speed is a constant.

f(t) = t at speed 1
To simplify things it would be great to fit one phase of the sine function into the range of 0-1. Fortunately Unreal is kind enough to have that built in (I should have researched that first, I spent a good time scratching my head about it). Otherwise it would be fairly easy to do manually, since we know that 1 phase of sine is 2π, so the function would have to look like this: f(x) = sin(x*2π).


So this is up to the point, that the video shows. The problem is, that the sine function covers a far greater distance in 1 second, 4 units to be exact, however we want it to be equal to the distance the UVs cover. So whe need to divide it by 4/ multiply by 0.25 to fix that. Also since the drop center can only be in the UV range from -.5 to .5 I further multiply the function by (.5 - drop radius) to prevent it from leaving that space.
The last thing to do is offsetting the time input and there we go. The graph below illustrates the Y-Position change of the drop center over time.

Drop Y-Coordinate progression

Setup in UE4


This is getting there. It'd probably better to use a function that is not as uniform as the Sine-Function, maybe a combination of them, but I decided to keep it simple for now and really understand, what is going on mathematically, before trying something more ambitious.
This basically covers the Y-Axis movement.

In a next step I wanted to create a mask for the trails a raindrop would leave on a foggy surface. The main problem here is, that I won't be able to have the raindrops leave behind trails that stay. I will have to add some static ones to have that effect.

I ended up utilizing the UVs again to create 3 masks to then combine into the final mask.

Trail Masks

Trail Masks MF

 Combining them with the drops looks like this now. As I said the trails are not permanent, they fade out pretty quickly. I might add a control for how much trail appears behind the drop.


After finishing that part I wanted to go back to something easy again, so I added the same option of removing some of the drops as I did in the other Material Function.
This is how the Function looks at this point:

Overview 001
Obviously this is still very far from how I want it to look so in the next step I tackled giving the drops a kinda wiggly movement on the X-Axis. Since using sine-waves has worked before I decided to try and utilize them for this as well.
I tried out a few ways of combining sine waves at different frequencies.

f(x) = sin(2x) * sin(3x)

f(x) = sin(2x) + sin(3x)

I really liked the outcome of the second function, this method works well unless the difference in the frequencies is too high. With some small modifications, like changing the frequency for each drop by multiplying the frequency by the random value and remapping it to fit the X-Axis space of each cell I now had to somehow use it to make the drops wiggle and draw the trail.

What I did is using the green Y-Coordinates of the UVs (before they go into the panner node) and used that as the input for the sine-functions, which gave the following result:

X-Offset
The output of the marked multiply node goes into the x-position of the drop's center position, which makes the drop move, however the trail is still a straight line.
To do that I added the inverse(otherwise the trail and drop position are mirrored) of that to the panning UVs, masked out the red channel and getting the absolute values of that. I then use a smoothstep again to get the trails to the thickness of the rain drops.



And here is a clip of how all of that looks combined now.


This is starting to get closer to what I want this to look. I already know, that I will have to overlay a couple of those functions to create a more chaotic feeling.
Next I wanted to add some further distortion, utilising the same technique as with the other Rain Drop Material Function, using a normal map for that.

Distortion 


What I want to point out is that I will definitely still have to do some tweaking of the Parameters and figure out how to improve some bits, but now with less than a month left for finishing the FMP I will have to accept, that some parts might not turn out the way I want them to turn out.


The last thing I did was creating the normal map for the drops. It is not accurate, however it will help distorting the other textures to give the feeling of refraction.


Overview
This kinda wraps up all that went into the two Rain Material Functions, I hope it was somewhat understandable. I put a lot of time into constructing them and learned a lot of new things, especially manipulating UVs to create procedural shapes. It was certainly a lot of fun.
Since I still have to combine them and implement them into the other Shaders I will show the finished results in a different blog post.

3 comments:

  1. Looking great, love the mathematical approach to the worker and trail thickness

    ReplyDelete
    Replies
    1. Thanks. It certainly cost me a lot of nerves to get it working xD.

      Delete