Drawing Shapes to Render Textures

Last modified:

Here's an example of rendering Shapes to a render texture, rendering some shapes to a new RT once in Awake, using a camera

Image 498

I recommend using a disabled camera with culling mask set to None (to prevent it from rendering things in your scene), so that you can position and reason about projections more easily, in addition to having the camera pass important data into the shaders.

using Shapes;
using UnityEngine;

public class ShapesRT : MonoBehaviour {

// this camera component should be disabled,
// to prevent it from automatically rendering every frame
public Camera rtCamera;

void Awake() { // Create an RT
RenderTexture rt = new RenderTexture( 512, 512, 0, RenderTextureFormat.ARGB32 );
// I attached this script to a Unity quad for preview purposes
GetComponent<MeshRenderer>().material.mainTexture = rt;

rtCamera.targetTexture = rt; // make sure the camera is configured to target the RT
rt.DiscardContents( true, true ); // clear before drawing, in case you have old data in the RT
using( Draw.Command( rtCamera ) ) { // set up a Shapes draw command in the camera
Draw.RectangleBorder( Vector2.zero, new Vector2( 1, 1 ), 0.025f, 0.1f, Color.white );
Draw.Scale( 1f / 3f );
Draw.Line( Vector2.zero, Vector2.right, 0.15f, Color.red );
Draw.Line( Vector2.zero, Vector2.up, 0.15f, Color.green );
Draw.Disc( Vector2.zero, 0.15f, Color.white );

rtCamera.Render(); // Render the camera immediately


Note that Shapes uses premultiplied alpha blending, so if you want to display the RT correctly - here's an unlit premultiplied alpha shader, drawing a single texture, which you can use to preview the render results correctly. Unlit/Transparent works, but you will get dark borders around the edges since it isn't made for premultiplied data

You can also draw without the extra camera, but I don't recommend it, as it's less reliable when it comes to anti-aliasing and pixel scaling since there's no camera information to read from on a shader level. You also won't get the benefits of GPU instancing, as you have to use the direct drawing mode instead of the draw commands:

RenderTexture.active = rt;
GL.LoadProjectionMatrix( Matrix4x4.TRS( Vector3.zero, Quaternion.identity, Vector3.one ) );
Draw.Disc( Vector2.zero, 0.1f, Color.red );

This article was helpful for 16 people. Is this article helpful for you?