source | The region of the render target to read from. |
destX | The horizontal pixel position in the texture to write the pixels to. |
destY | The vertical pixel position in the texture to write the pixels to. |
recalculateMipMaps | If this parameter is true , Unity automatically recalculates the mipmaps for the texture after writing the pixel data. Otherwise, Unity does not do this automatically. |
Reads the pixels from the current render target (the screen, or a RenderTexture), and writes them to the texture.
This method copies a rectangular pixel area from the currently active render target, and writes it to the texture at the position defined by destX
and destY
. Both coordinates use pixel space: (0,0) is lower left.
Note: If you just want to copy the pixels from one texture to another and do not need to manipulate the pixel data on the CPU, it is faster to perform a GPU-to-GPU copy of the pixel data with Graphics.CopyTexture, CommandBuffer.CopyTexture, or Graphics.Blit.
For this function to succeed, Texture.isReadable must be true
, the render target and the texture must use the same format, and the format must be supported on the device for both rendering and sampling.
If you choose not to automatically update mipmaps as part of this operation, you can do so manually when you call Texture2D.Apply.
The following code example demonstrates how to use ReadPixels
in the Built-in Render Pipeline. In the Scriptable Render Pipeline, Camera.onPostRender is not available, but you can use RenderPipelineManager.endCameraRendering
in a similar way.
using UnityEngine;
public class ReadPixelsExample : MonoBehaviour { // Set this reference to a GameObject that has a Renderer component, // and a material that displays a texure (such as the Default material). // A standard Cube or other primitive works for the purposes of this example. public Renderer screenGrabRenderer;
private Texture2D destinationTexture; private bool isPerformingScreenGrab;
void Start() { // Create a new Texture2D with the width and height of the screen, and cache it for reuse destinationTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
// Make screenGrabRenderer display the texture. screenGrabRenderer.material.mainTexture = destinationTexture;
// Add the onPostRender callback Camera.onPostRender += OnPostRenderCallback; }
void Update() { // When the user presses the space key, perform the screen grab operation if (Input.GetKeyDown(KeyCode.Space)) { isPerformingScreenGrab = true; } }
void OnPostRenderCallback(Camera cam) { if (isPerformingScreenGrab) { // Check whether the Camera that has just finished rendering is the one you want to take a screen grab from if (cam == Camera.main) { // Define the parameters for the ReadPixels operation Rect regionToReadFrom = new Rect(0, 0, Screen.width, Screen.height); int xPosToWriteTo = 0; int yPosToWriteTo = 0; bool updateMipMapsAutomatically = false;
// Copy the pixels from the Camera's render target to the texture destinationTexture.ReadPixels(regionToReadFrom, xPosToWriteTo, yPosToWriteTo, updateMipMapsAutomatically);
// Upload texture data to the GPU, so the GPU renders the updated texture // Note: This method is costly, and you should call it only when you need to // If you do not intend to render the updated texture, there is no need to call this method at this point destinationTexture.Apply();
// Reset the isPerformingScreenGrab state isPerformingScreenGrab = false; } } }
// Remove the onPostRender callback void OnDestroy() { Camera.onPostRender -= OnPostRenderCallback; } }
See Also: ImageConversion.EncodeToPNG.