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.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Creating Snow Trails in Unreal Engine 4
25 mins
- Getting Started
- Snow Trails Implementation
- Capturing From the Bottom
- Creating the Depth Check Material
- Creating the Scene Capture
- Setting the Capture Area Size
- Storing the Capture Size
- Deforming the Landscape
- Projecting the Render Target
- Using the Render Target
- Creating Persistent Trails
- Creating the Persistent Buffer
- Writing Back to the Capture
- Moving the Capture
- Moving the Capture in Discrete Steps
- Moving the Persistent Buffer
- Where to Go From Here?
Creating the Scene Capture
First, you need a render target for the scene capture to write to. Navigate to the RenderTargets folder and create a new Render Target named RT_Capture.
Now let’s create the scene capture. For this tutorial, you will add a scene capture to a Blueprint since you will need to do some scripting for it later on. Open Blueprints\BP_Capture and then add a Scene Capture Component 2D. Name it SceneCapture.
First, you need to set the capture’s rotation so that it looks up towards the ground. Go to the Details panel and set Rotation to (0, 90, 90).
Up next is the projection type. Since the mask is a 2D representation of the scene, you need to remove any perspective distortion. To do this, set Projection\Projection Type to Orthographic.
Next, you need to tell the scene capture which render target to write to. To do this, set Scene Capture\Texture Target to RT_Capture.
Finally, you need to use the depth check material. Add PP_DepthCheck to Rendering Features\Post Process Materials. In order for post processing to work, you also need to change Scene Capture\Capture Source to Final Color (LDR) in RGB.
Now that the scene capture is all set up, you need to specify the size of the capture area.
Setting the Capture Area Size
Since it’s best to use low resolutions for the render target, you need to make sure you are using its space efficiently. This means deciding how much area one pixel covers. For example, if the capture area and render target’s resolution are the same size, you get a 1:1 ratio. Each pixel will cover a 1×1 area (in world units).
For snow trails, a 1:1 ratio is not required since it is unlikely you will need that much detail. I recommend using higher ratios since they will allow you to increase the size of the capture area while still using a low resolution. Be careful not to increase the ratio too much otherwise you will start to lose detail. For this tutorial, you will use an 8:1 ratio which means the size of each pixel is 8×8 world units.
You can adjust the size of the capture area by changing the Scene Capture\Ortho Width property. For example, if you wanted to capture a 1024×1024 area, you would set it to 1024. Since you are using an 8:1 ratio, set this to 2048 (the default render target resolution is 256×256).
This means the scene capture will capture a 2048×2048 area. This is approximately 20×20 metres.
The ground material will also need access to the capture size to project the render target correctly. An easy way to do this is to store the capture size into a Material Parameter Collection. This is basically a collection of variables that any material can access.
Storing the Capture Size
Go back to the main editor and navigate to the Materials folder. Afterwards, create a Material Parameter Collection which is listed under Materials & Textures. Rename it to MPC_Capture and then open it.
Next, create a new Scalar Parameter and name it CaptureSize. Don’t worry about setting its value — you will do this in Blueprints.
Go back to BP_Capture and add the highlighted nodes to Event BeginPlay. Make sure to set Collection to MPC_Capture and Parameter Name to CaptureSize.
Now any material can get the value of Ortho Width by reading from the CaptureSize parameter. That’s it for the scene capture for now. Click Compile and then go back to the main editor. The next step is to project the render target onto the ground and use it to deform the landscape.
Deforming the Landscape
Open M_Landscape and then go to the Details panel. Afterwards, Set the following properties:
- Two Sided set to enabled. Since the scene capture will be looking from the bottom, it will only see the ground’s backfaces. By default, the engine does not render backfaces. This means it will not store the ground’s depth into the depth buffer. To fix this, you need to tell the engine to render both sides of the mesh.
- D3D11 Tessellation set to Flat Tessellation (you can also use PN Triangles). Tessellation will split a mesh’s triangles into smaller triangles. This effectively increases the resolution of the mesh and allows you to get finer detail when displacing vertices. Without this, the vertex density would be too low to produce a convincing trail.
Once you have tessellation enabled, World Displacement and Tessellation Multiplier will be enabled.
Tessellation Multipler controls the amount of tessellation. For this tutorial, leave this unplugged which means it will use the default value of 1.
World Displacement takes in a vector value describing which direction to move the vertex and by how much. To calculate the value for this pin, you first need to project the render target onto the ground.
Projecting the Render Target
To project the render target, you need to calculate its UV coordinates. To do this, create the following setup:
Summary:
- First, you need to get the XY position of the current vertex. Since you are capturing from the bottom, the X coordinate is flipped so you need to flip it back (if you were capturing from the top, you wouldn’t need to do this).
- This section will actually do two things. First, it will center the render target so that the middle is at (0, 0) in world space. It will then convert from world space to UV space.
Next, create the highlighted nodes and connect the previous calculation as shown below. Make sure to set the Texture Sample’s texture to RT_Capture.
This will project the render target onto the ground. However, any vertices outside of the capture area will sample the edges of the render target. This is an issue because the render target is only meant to be used on vertices inside the capture area. Here’s what it would look like in-game:
To fix this, you need to mask out any UVs that fall outside the 0 to 1 range (the capture area). The MF_MaskUV0-1 function is a function I built to do this. It will return 0 if the provided UV is outside the 0 to 1 range and return 1 if it is within range. Multiplying the result with the render target will perform the masking.
Now that you have projected the render target, you can use it to blend colors and displace vertices.