Unreal Engine 4 Tutorial: Painting With Render Targets
A render target is basically a texture that you can write to at runtime. On the engine side of things, they store information such as base color, normals and ambient occlusion.
On the user side of things, render targets were mainly used as a sort of secondary camera. You could point a scene capture at something and store the image to a render target. You could then display the render target on a mesh to simulate something like a security camera.
With the release of 4.13, Epic introduced the ability to draw materials directly to render targets using Blueprints. This feature allowed for advanced effects such as fluid simulations and snow deformation. Sounds pretty exciting, right? But before you get into such advanced effects, it’s always best to start simple. And what’s more simple than just painting onto a render target?
In this tutorial, you will learn how to:
- Dynamically create a render target using Blueprints
- Display a render target on a mesh
- Paint a texture onto a render target
- Change the brush size and texture during gameplay
- Part 1: Painting With Render Targets (you are here!)
- Part 2: Deformable Snow
- Part 3: Interactive Grass
Start by downloading the materials for this tutorial (you can find a link at the top or bottom of this tutorial). Unzip it and navigate to CanvasPainterStarter and open CanvasPainter.uproject. If you press Play, you will see the following:
The square in the middle (the canvas) is what you will be painting on. The UI elements on the left will be the texture you want to paint and its size.
To start, let’s go over the method you will use to paint.
The first thing you will need is a render target to act as the canvas. To determine where to paint the render target, you do a line trace going forward from the camera. If the line hits the canvas, you can get the hit location in UV space.
For example, if the canvas is perfectly UV mapped, a hit in the center will return a value of (0.5, 0.5). If it hits the bottom-right corner, you will get a value of (1, 1). You can then use some simple math to calculate the draw location.
But why get the location in UV space? Why not use the actual world space location? Using world space, you would first need to calculate the hit’s location relative to the plane. You would also need to take into account the plane’s rotation and scale.
Using UV space, you don’t need to do any of these calculations. On a perfectly UV mapped plane, a hit in the middle will always return (0.5, 0.5), regardless of the plane’s location and rotation.
First, you will create the material that will display the render target.
Creating the Canvas Material
Navigate to the Materials folder and then open M_Canvas.
For this tutorial, you will create render targets dynamically in Blueprints. This means you will need to set up a texture as a parameter so you can pass in the render target. To do this, create a TextureSampleParameter2D and name it RenderTarget. Afterwards, connect it to BaseColor.
Don’t worry about setting the texture here — you will do this next in Blueprints. Click Apply and then close M_Canvas.
The next step is to create the render target and then use it in the canvas material.
Creating the Render Target
There are two ways to create render targets. The first is to create them in the editor by clicking Add New\Materials & Textures\Render Target. This will allow you to easily reference the same render target across multiple actors. However, if you wanted to have multiple canvases, you would have to manually create a render target for each canvas.
A better way to do this is to create render targets using Blueprints. The advantage to this is that you only create render targets as needed and they do not bloat your project files.
First, you will need to create the render target and store it as a variable for later use. Go to the Blueprints folder and open BP_Canvas. Locate Event BeginPlay and add the highlighted nodes.
Set Width and Height to 1024. This will set the resolution of the render target to 1024×1024. Higher values will increase image quality but at the cost of more video memory.
Next is the Clear Render Target 2D node. You can use this node to set the color of your render target. Set Clear Color to (0.07, 0.13, 0.06). This will fill the entire render target with a greenish color.
Now you need to display the render target on the canvas mesh.
Displaying the Render Target
At the moment, the canvas mesh is using its default material. To display the render target, you need to create a dynamic instance of M_Canvas and supply the render target. Then, you need to apply the dynamic material instance to the canvas mesh. To do this, add the highlighted nodes:
First, go to the Create Dynamic Material Instance node and set Parent to M_Canvas. This will create a dynamic instance of M_Canvas.
Next, go to the Set Texture Parameter Value node and set Parameter Name to RenderTarget. This will pass in the render target to the texture parameter you created before.
Now the canvas mesh will display the render target. Click Compile and then go back to the main editor. Press Play to see the canvas change colors.
Now that you have your canvas, you need to create a material to act as your brush.