Thanks to https://stackoverflow.com/a/79090687/22588434 for pointing out using Graphics.Blit
- it is much more efficient in the GPU.
I needed the following (for Unity 6 at least) to correctly vertically flip a RenderTexture
(note both Vector2 parameters):
Graphics.Blit(srcTexture, destRenderTexture, new Vector2(1, -1), new Vector2(0, 1));
srcTexture
is a Texture (RenderTexture, Texture2D, etc). destRenderTexture
must be a RenderTexture, GraphicsTexture, or Material according to the latest docs.
If you need to get back a Texture2D
, you can still use Graphics.Blit
to do the flipping in the GPU to a RenderTexture
, and then request an async gpu readback into a Texture2D
. Such as:
AsyncGPUReadback.Request(destRenderTexture, 0, TextureFormat.RGBA32, request =>
{
// width/height must match destRenderTexture
var texture2D = new Texture2D(width, height, TextureFormat.RGBA32, false);
texture2D.LoadRawTextureData(request.GetData<float>());
texture2D.Apply();
// ... use texture2D
});
Otherwise, if you just need a method to flip a given RenderTexture
, I found this function on a github gist while researching the correct scale/offset parameters above: https://gist.github.com/mminer/816ff2b8a9599a9dd342e553d189e03f
/// <summary>
/// Vertically flips a render texture in-place.
/// </summary>
/// <param name="target">Render texture to flip.</param>
public static void VerticallyFlipRenderTexture(RenderTexture target)
{
var temp = RenderTexture.GetTemporary(target.descriptor);
Graphics.Blit(target, temp, new Vector2(1, -1), new Vector2(0, 1));
Graphics.Blit(temp, target);
RenderTexture.ReleaseTemporary(temp);
}