Creating Snow Trails in Unreal Engine 4

In this Unreal Engine 4 tutorial, you will learn how to create deformable snow trails using a scene capture and render targets By Tommy Tran.

4.7 (29) · 2 Reviews

Download materials
Save for later
Share
You are currently viewing page 3 of 4 of this article. Click here to view the first page.

Using the Render Target

Let’s start with blending colors. To do this, simply connect the 1-x to the Lerp like so:

unreal engine snow

Note: If you’re wondering why I’m using a 1-x, it’s just to invert the render target and make calculations a bit simpler.

Now when there is a trail, the ground’s color will be brown. If there is no trail, it will be white.

The next step is to displace the vertices. To do this, add the highlighted nodes and connect everything like so:

unreal engine snow

This will cause all snow areas to move up by 25 units. Non-snow areas will have zero displacement which is what creates the trail.

Note: You can change DisplacementHeight to decrease or increase the height of the snow. Also notice that DisplacementHeight is the same value as the capture offset. Setting them to the same value will give an accurate deformation. But there are cases where you might want to change them individually which is why I’ve left them as separate parameters.

Click Apply and then go back to the main editor. Create an instance of BP_Capture in the level and set its location to (0, 0, -2000) to place it underneath the ground. Press Play and walk around using W, A, S and D to start deforming the snow.

unreal engine snow

The deformation is working but there aren’t any trails! This is because the capture overwrites the render target every time it captures. What you need here is some way to make the trails persistent.

Creating Persistent Trails

To create persistency, you need another render target (the persistent buffer) to store the contents of the capture before it gets overwritten. Afterwards, you add the persistent buffer back to the capture (after it gets overwritten). What you get is a loop where each render target writes to the other. This is what creates the persistency.

unreal engine snow

First, you need to create the persistent buffer.

Creating the Persistent Buffer

Go to the RenderTargets folder and create a new Render Target named RT_Persistent. For this tutorial, you don’t have to change any texture settings but for your own project, make sure both render targets use the same resolution.

Next, you need a material that will copy the capture to the persistent buffer. Open Materials\M_DrawToPersistent and then add a Texture Sample node. Set its texture to RT_Capture and connect it like so:

unreal engine snow

Now you need to use the draw material. Click Apply and then open BP_Capture. First, let’s create a dynamic instance of the material (you will need to pass in values later on). Add the highlighted nodes to Event BeginPlay:

The Clear Render Target 2D nodes will make sure each render target is in a blank slate before use.

Next, open the DrawToPersistent function and add the highlighted nodes:

unreal engine snow

Next, you need to make sure you are drawing to the persistent buffer every frame since the capture happens every frame. To do this, add DrawToPersistent to Event Tick.

unreal engine snow

Finally, you need to add the persistent buffer back to the capture render target.

Writing Back to the Capture

Click Compile and then open PP_DepthCheck. Afterwards, add the highlighted nodes. Make sure to set the Texture Sample to RT_Persistent:

unreal engine snow

Now that the render targets are writing to each other, you’ll get persistent trails. Click Apply and then close the material. Press Play and start making trails!

unreal engine snow

The result is looking great but the current setup only works for one area of the map. If you walk outside of the capture area, trails will stop appearing.

unreal engine snow

A way to get around this is move the capture area with the player. This means trails will always appear around the player’s area.

Note: Since the capture is moving, any information outside the capture area is discarded. This means if you go back to an area that previously had trails, they will no longer be there. Stay tuned for the next tutorial where I’ll show you how to create semi-persistency.

Moving the Capture

You might think that all you have to do is set the capture’s XY position to the player’s XY position. But if you do this the render target will start to blur. This is because you are moving the render target in steps that are smaller than a pixel. When this happens, a pixel’s new location will end up being between pixels. This results in multiple pixels interpolating to a single pixel. Here’s what it looks like:

unreal engine snow

To fix this, you need to move the capture in discrete steps. What you do is calculate the world size of a pixel and then move the capture in steps equal to that size. Now each pixel will never end up inbetween other pixels and therefore no blurring occurs.

To start, let’s create a parameter to hold the capture’s location. The ground material will need this for the projection math. Open MPC_Capture and add a Vector Parameter named CaptureLocation.

unreal engine snow

Next, you need to update the ground material to use the new parameter. Close MPC_Capture and then open M_Landscape. Modify the first section of the projection math to this:

unreal engine snow

Now the render target will always be projected at the capture’s location. Click Apply and then close the material.

Up next is to move the capture in discrete steps.

Moving the Capture in Discrete Steps

To calculate the pixel’s world size, you can use the following equation:

(1 / RenderTargetResolution) * CaptureSize

To calculate the new position, use the equation below on each position component (in this case, the X and Y positions).

(floor(Position / PixelWorldSize) + 0.5) * PixelWorldSize

Now let’s use those in the capture Blueprint. To save time, I have created a SnapToPixelWorldSize macro for the second equation. Open BP_Capture and then open the MoveCapture function. Afterwards, create the following setup:

unreal engine snow

This will calculate the new location and then store the difference between the new and current locations into MoveOffset. If you are using a resolution other than 256×256, make sure you change the highlighted value.

Next, add the highlighted nodes:

unreal engine snow

This will move the capture using the calculated offset. Then it will store the capture’s new location into MPC_Capture so the ground material can use it.

Finally, you need to perform the position update every frame. Close the function and then add MoveCapture before DrawToPersistent in Event Tick.

unreal engine snow

Moving the capture is only half of the solution. You also need to shift the persistent buffer as the capture moves as well. Otherwise, the capture and persistent buffer will desync and produce strange results.

unreal engine snow

Tommy Tran

Contributors

Tommy Tran

Author

Over 300 content creators. Join our team.