Breakdown: Animated Raindrop Material in UE4

Breakdown: Animated Raindrop Material in UE4

Harry “deBug” Emelianov kindly prepared a step-by-step breakdown of his animated Raindrop opaque and transparent materials made in UE4.

Harry “deBug” Emelianov kindly prepared a step-by-step breakdown of his animated Raindrop opaque and transparent materials made in UE4.


Hi! My name is Harry “deBug” Emelianov, I’m a self-taught artist from Moscow.

CG became my hobby when I was 14. I had been doing ArchViz and high poly modeling, but my love for computer games led me to Gamedev. At that time, I began learning about game engines (UE3 and Unity4 back then), plus learning C#, C++ and how to write shaders using GLSL and HLSL. For some time, I outsourced for TraceStudio and Fox3D, participated in a lot of interesting projects like Call of Duty: Infinite Warfare, Arktika 1, A Plague Tale: Innocence and many other. Now I am working as a freelancer and teach courses on environment design and game textures at ScreamSchool in Moscow.

Animated Textures in UE4

Unreal Engine is great for creating simple and good-looking animated shaders and effects since it doesn’t require strong programming skills, just basic knowledge of math. You need two parameters for the adjustment of animated materials: time-dependent coordinates that would change the texture and, as you probably have already guessed, time.

Raindrop Material

The workflow for the animated drops was pretty much the same. I began with making a few static textures which contained the information necessary for the material.

It required to create a few maps:

  • A normal map for static drops, and packed masks.
  • R, a time shift mask, responsible for drops appearing and disappearing at the right time.
  • G, a mask for blending drops with the surface.
  • B, a noize mask to make the drops appearing more chaotical.
  • A normal map for moving drops, and packed masks.
  • R, a mask for the drop itself.
  • G, a mask for the path of the drop which doesn’t allow other static drops appear on the way of the running drop.
  • And a normal map of the distortion which influences the manner of how the drops flow over the surface making it more irregular.

Then, I made two filters with all necessary information and logic. They are divided into two groups: for static drops appearing and disappearing with time and for animated drops flowing over the surface.


At first, we need to take the coordinates of the texture and begin to displace them in the necessary direction. Later, we will use these coordinates to sample the normal map of distortion and add a slight distortion to the texture coordinates of the drops. With the information about distortion and texture coordinates displacement, we can sample our normals and masks. However, in order to make more than just simple drops flowing, I used the red channel of our mask and made its intensity change through time. Plus I also made drops appear and disappear within time by adding a few simple math functions.

The same thing with the second filter. It contains displacing texture coordinates and distortions but with a slight difference. When I was making the texture of our flowing drops, I made just one drop and one set of masks for it. In order to populate drops, I had to add a loop where the drops were copied, displaced, had different speed (unique for each drop), and were finally blended with each other. To make the distortion more interesting, I used the distortion map twice: for the large distortions and for less intensive ones. Then, they were blended together with different intensity along the axis. Hypothetically, it is possible to use more than one drop in a map or one map for all the drops, but in that case, all the drops will move at the same speed parallel to each other, because you won’t able to influence the speed and time of a single drop.

I also have a custom node with information about the maximum number of the drops and made a static array set with current position and speed of a drop. It can be accomplished either manually or in Unreal, but I used an old script for 3ds Max.  

This script takes the information about the position and size of a chosen object(s) in the editor and returns it into the defined arrays. In my case, I used only XY coordinates, and an index of the speed of a drop falling. Similarly, we can create an array with information about the size of the drop and add it to the material.

When the filters were ready, I adjusted their output parameters. I also created a few input parameters, which could be changed in the materials, for example, the speed of the animation, tiling, drops distortion intensity, normal map intensity, and textures that use the filters.

After that, these filters can be used in any material irrespectively of its type. The parameters of the material can be adjusted with the help of its masks.   

The first base material I made as an example was a matte opaque surface, a starting point for blending necessary masks and setting such parameters as color, roughness, and normals for drops.

If we change the material type to transparent and similarly add transparency and distortion, we will get a simple glass material.

To make the object even more interesting and complex, we can add a condensation effect by blurring the background behind the glass. This trick works only for transparent materials and post-processes. We also have to lower the level of transparency, still keeping the material type transparent. After that, it is time to add the blur effect to the material.

Then you can add a mask to avoid moving drops on the surfaces parallel to the ground.

In the same way, we can blend it with existing textures, for example, the textures of the roof the drops are falling from, or any other material.

Here’s an example of using the filters in post-processing:


Unfortunately, all these effects are very demanding which means that they are more suitable for small surfaces which don’t take much space on the screen. Like windows in the rooms, for example.

The more textures, blends, and complicated math are used, the more difficult the material will be for rendering.  

For optimization, we can simplify the textures, e.g. reduce their size or get rid of some math if we don’t want this or that effect. In the case of this filter, I didn’t aim for some specific results and tried to make something multipurpose that can be simplified if necessary.   

In conclusion, I want to thank you for your attention and mention that this article was written based on the new version of the filter. Both versions can be downloaded for free from Gumroad.

If you found this article interesting, below we are listing a couple of related Unity Store Assets that may be useful for you.

Harry “deBug” Emelianov, 3D Artist

Interview conducted by Kirill Tokarev

Join discussion

Comments 10

  • .cn xl



    .cn xl

    ·2 years ago·
  • gk*

    Thank you ! That is really inspiring ,I hope I can handle it.



    ·3 years ago·
  • Eric Kiser

    Great Job


    Eric Kiser

    ·3 years ago·
  • Cock James

    Just amazing!!! Thanks for sharing this is super inpirational


    Cock James

    ·3 years ago·
  • Anonymous user

    wow! Awesome!


    Anonymous user

    ·3 years ago·
  • daria

    Thank you for the questions, guys! Harry added a small part about post processing and corrected the channels part.



    ·3 years ago·
  • Pixel_Error

    As always, great tutorial!



    ·3 years ago·
  • Stefan

    How can we use this in lets say a post process volume?



    ·3 years ago·
  • Ali

    Wow, for me this is up there with the quality of stuff Ryan Brucks makes - fantastic work!



    ·3 years ago·
  • tor3203

    Where's B channel go? It's missing

    It required to create a few maps:
    A normal map for static drops, and packed masks.
    R, a time shift mask, responsible for drops appearing and disappearing at the right time
    G, a noize mask to make the drops appearing more chaotical.
    A normal map for moving drops, and packed masks.



    ·3 years ago·

You might also like

We need your consent

We use cookies on this website to make your browsing experience better. By using the site you agree to our use of cookies.Learn more