/// <summary> /// Perform the readback from the provided Render texture using ReadPixels API. /// </summary> /// <param name="renderTexture">Input source Render texture for the readback.</param> /// <returns>Returns a byte array of the RGB data retrieved from the readback.</returns> /// <exception cref="NotSupportedException"></exception> public static byte[] GetPixelsSlow(RenderTexture renderTexture) { using (s_GetPixelsSlow.Auto()) { var pixelSize = GraphicsUtilities.GetBlockSize(renderTexture.graphicsFormat); var channels = GraphicsFormatUtility.GetComponentCount(renderTexture.graphicsFormat); var channelSize = pixelSize / channels; var rect = new Rect(0, 0, renderTexture.width, renderTexture.height); // for RGB(A) we can just return the raw data. if (channels >= 3 && channels <= 4) { var texture = new Texture2D(renderTexture.width, renderTexture.height, renderTexture.graphicsFormat, TextureCreationFlags.None); RenderTexture.active = renderTexture; texture.ReadPixels(rect, 0, 0); texture.Apply(); RenderTexture.active = null; var data = texture.GetRawTextureData <byte>().ToArray(); UnityEngine.Object.Destroy(texture); return(data); } else { Debug.Assert(channels == 1, "Can only handle a single channel RT."); // Read pixels must be one of RGBA32, ARGB32, RGB24, RGBAFloat or RGBAHalf. // So R16 and RFloat will be converted to RGBAFloat. var texture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.RGBAFloat, false); RenderTexture.active = renderTexture; texture.ReadPixels(rect, 0, 0); texture.Apply(); RenderTexture.active = null; var length = renderTexture.width * renderTexture.height; var input = texture.GetRawTextureData <float>().ToArray(); UnityEngine.Object.Destroy(texture); Array output = null; int index = 0; switch (channelSize) { case 2: if (GraphicsFormatUtility.IsSignedFormat(renderTexture.graphicsFormat)) { short[] shorts = ArrayUtilities.Allocate <short>(length); var si = 0; while (index < length) { shorts[index++] = (short)((float)short.MaxValue * input[si]); si += 4; } output = shorts; } else { ushort[] ushorts = ArrayUtilities.Allocate <ushort>(length); var si = 0; while (index < length) { ushorts[index++] = (ushort)((float)ushort.MaxValue * input[si]); si += 4; } output = ushorts; } break; case 4: float[] floats = ArrayUtilities.Allocate <float>(length); var fi = 0; while (index < length) { floats[index++] = input[fi]; fi += 4; } output = floats; break; default: throw new NotSupportedException(); } return(ArrayUtilities.Cast <byte>(output)); } } }