Creating a Sprite from Camera View in Unity

A simple guide to creating a Sprite from the Camera view using RenderTexture and Texture2D in Unity.

Creating sprites from what a camera sees is useful in many scenarios. Some examples include:

  • generating screenshots of the gameplay
  • creating a mini-map of the scene from the top view
  • creating a virtual camera inside the game that allows players to take pictures of the scene and save the captured photo as an image file
  • creating visual effects by modifying the game scene

Generating an image from the camera's view involves a few simple steps.

Creating a Sprite

To create a sprite, first of all, we need a camera. Then we generate a Texture2D object to hold the data from the rendered camera view. We can use a separate camera or main camera to generate the texture.

Create a new camera, or obtain the reference of an existing camera from the scene.

public Camera camera;

// obtain the reference ...

Create a RenderTexture instance

Then, create a new instance of RenderTexture with the required dimensions. To create a render texture, we need to specify width and height in pixels and its color depth. We can optionally specify the Render Texture format. Render texture is just a type of texture that can be updated at runtime. Our camera will update this when we want to render texture.

int height = 1024; // output texture height
int width = 1024; // output texture height
int depth = 24;	// output texture color depth

RenderTexture renderTexture = new RenderTexture(width, height, depth);

Set the camera's target texture

Now, we set the camera's target texture to the instance of RenderTexture we just created so that the camera's view is rendered into it.

camera.targetTexture = renderTexture;

Create a Texture2D object

Next, we need to create an instance of Texture2D to hold our texture data. We will create it in the same size as our instance of RenderTexture. A new Rect should also be created to specify the region of texture that we are interested in. For now, let's take the whole area – starting from the top left corner all the way to the bottom right corner.

Texture2D texture = new Texture2D(width, height, TextureFormat.RGBA32, false);
Rect rect=new Rect(0, 0, width, height);

Capture the texture from the camera

Now we are ready to capture texture from the camera. To do this, just call The Render() method of our Camera instance.

The next step is to plot the contents of the RenderTexture instance into our texture.

camera.Render();

RenderTexture currentRenderTexture = RenderTexture.active;
RenderTexture.active = renderTexture;
texture.ReadPixels(rect, 0, 0);
texture.Apply();

The Texture2D.ReadPixels() method will plot pixels from currently active RenderTexture instance. We have set the currently active render texture to our previous instance of RenderTexture. The currentRenderTexture variable keeps track of previously active RenderTexture so that we can reset active RenderTexture when we are done. The Texture2D.Apply() method will apply changes from ReadPixels() to our texture.

Cleaning Up

Now we need to do some cleaning up to our changes.

 //reset camera’s target texture
camera.targetTexture = null;
// reset active renderTexture
RenderTexture.active = currentRenderTexture; 
// free some memory?
Destroy( renderTexture );

Generating a sprite from texture2D

Then we can generate sprite from the newly created instance of Texture2D.

Sprite sprite = Sprite.Create( texture, rect, Vector2.zero );

The sprite variable contains the required sprite that we can use.

Final Code

Finally, the complete code will look like this:

//get reference of camera from inspector
public Camera camera;
int height = 1024;
int width = 1024;
int depth = 24;

//method to render from camera
public Sprite CaptureScreen() 
{
    RenderTexture renderTexture = new RenderTexture(width, height, depth);
    Rect rect = new Rect(0,0,width,height);
    Texture2D texture = new Texture2D(width, height, TextureFormat.RGBA32, false);

    camera.targetTexture = renderTexture;
    camera.Render();

    RenderTexture currentRenderTexture = RenderTexture.active;
    RenderTexture.active = renderTexture;
    texture.ReadPixels(rect, 0, 0);
    texture.Apply();

    camera.targetTexture = null;
    RenderTexture.active = currentRenderTexture;
    Destroy(renderTexture);

    Sprite sprite = Sprite.Create(texture, rect, Vector2.zero);

    return sprite;
}
A method to return sprite from a camera's view.

So, that's all about extracting what the camera sees into a Sprite so that we can do further post-processing like masking or saving as an image.