-
-
Save krzys-h/76c518be0516fb1e94c7efbdcd028830 to your computer and use it in GitHub Desktop.
using UnityEngine; | |
using UnityEditor; | |
public class SaveRenderTextureToFile { | |
[MenuItem("Assets/Save RenderTexture to file")] | |
public static void SaveRTToFile() | |
{ | |
RenderTexture rt = Selection.activeObject as RenderTexture; | |
RenderTexture.active = rt; | |
Texture2D tex = new Texture2D(rt.width, rt.height, TextureFormat.RGB24, false); | |
tex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0); | |
RenderTexture.active = null; | |
byte[] bytes; | |
bytes = tex.EncodeToPNG(); | |
string path = AssetDatabase.GetAssetPath(rt) + ".png"; | |
System.IO.File.WriteAllBytes(path, bytes); | |
AssetDatabase.ImportAsset(path); | |
Debug.Log("Saved to " + path); | |
} | |
[MenuItem("Assets/Save RenderTexture to file", true)] | |
public static bool SaveRTToFileValidation() | |
{ | |
return Selection.activeObject is RenderTexture; | |
} | |
} |
using UnityEngine; | |
using UnityEditor; | |
public class SaveScreenshotToFile { | |
[MenuItem("Custom/Render Camera to file")] | |
public static void RenderCameraToFile() | |
{ | |
Camera camera = Selection.activeGameObject.GetComponent<Camera>(); | |
RenderTexture rt = new RenderTexture(2560, 1440, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB); | |
RenderTexture oldRT = camera.targetTexture; | |
camera.targetTexture = rt; | |
camera.Render(); | |
camera.targetTexture = oldRT; | |
RenderTexture.active = rt; | |
Texture2D tex = new Texture2D(rt.width, rt.height, TextureFormat.RGB24, false); | |
tex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0); | |
RenderTexture.active = null; | |
byte[] bytes = tex.EncodeToPNG(); | |
string path = "Assets/screenshot.png"; | |
System.IO.File.WriteAllBytes(path, bytes); | |
AssetDatabase.ImportAsset(path); | |
Debug.Log("Saved to " + path); | |
} | |
[MenuItem("Custom/Render Camera to file", true)] | |
public static bool RenderCameraToFileValidation() | |
{ | |
return Selection.activeGameObject != null && Selection.activeGameObject.GetComponent<Camera>() != null; | |
} | |
} |
Thanks. It helps me a lot.
Thank you!!
Thank you!! Here's a remix that takes a shot directly from the camera
static void SaveRenderTexture(RenderTexture rt, string path)
{
RenderTexture.active = rt;
Texture2D tex = new Texture2D(rt.width, rt.height, TextureFormat.RGB24, false);
tex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
RenderTexture.active = null;
var bytes = tex.EncodeToPNG();
System.IO.File.WriteAllBytes(path, bytes);
AssetDatabase.ImportAsset(path);
Debug.Log($"Saved texture: {rt.width}x{rt.height} - " + path);
}
[MenuItem("Assets/Take Screenshot", true)]
public static bool TakeScreenshotValidation() =>
Selection.activeGameObject && Selection.activeGameObject.GetComponent<Camera>();
[MenuItem("Assets/Take Screenshot")]
public static void TakeScreenshot()
{
var camera = Selection.activeGameObject.GetComponent<Camera>();
var prev = camera.targetTexture;
var rt = new RenderTexture(Screen.width, Screen.height, 16);
camera.targetTexture = rt;
camera.Render();
SaveRenderTexture(rt, "Assets/screenshot.png");
camera.targetTexture = prev;
Object.DestroyImmediate(rt);
}
Since this gist seems useful to so many people, I added a variant which generates a screenshot from a camera, and works correctly with linear color space. This became necessary when we switched to using linear color space, since there was no way to create an sRGB render texture through the UI, and colors were coming out all weird in the screenshot otherwise (because most normal image files are expected to be in sRGB, not linear).
Also, in case you were wondering, simply changing Texture2D
constructor parameter linear
to true
does not work, because ReadPixels
does not perform the linear to sRGB conversion in this case, only actually rendering with a shader does.
Thanks @mrchantey for reminding me I have this ;)
Thank you for publishing this. Very helpful!
Remember to call Object.Destroy(tex)
after you are done with the texture or it'll leak. See this example from unity docs
This is very helpful, thanks. But is there a way to retain the alpha information that the RT has?
EDIT: Turns out it was a simple as changing the texture format to TextureFormat.RGBA32
Thanks, helped a lot!
Would like to suggest making this gist a general png saver
https://gist.github.com/Thaina/44730376d4ef58bb52496d851634a531
if your having issues with SRGB to Linear color space( image is very dark compared), i found this change works
using UnityEngine;
using UnityEditor;
public class SaveRenderTextureToFile
{
[MenuItem("Assets/Save RenderTexture to file")]
public static void SaveRTToFile()
{
RenderTexture rt = Selection.activeObject as RenderTexture;
RenderTexture rtNew = new RenderTexture(rt.width, rt.height, 8, RenderTextureFormat.ARGB32);
Graphics.Blit(rt, rtNew);
RenderTexture.active = rtNew;
Texture2D tex = new Texture2D(rt.width, rt.height, TextureFormat.RGBA32, false);
tex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
RenderTexture.active = null;
byte[] bytes;
bytes = tex.EncodeToPNG();
string path = AssetDatabase.GetAssetPath(rt) + ".png";
System.IO.File.WriteAllBytes(path, bytes);
AssetDatabase.ImportAsset(path);
Debug.Log("Saved to " + path);
}
[MenuItem("Assets/Save RenderTexture to file", true)]
public static bool SaveRTToFileValidation()
{
return Selection.activeObject is RenderTexture;
}
}
To add an alpha support just change Texture2D tex = new Texture2D(rt.width, rt.height, TextureFormat.RGB24, false);
to Texture2D tex = new Texture2D(rt.width, rt.height, TextureFormat.RGBA32, false);
Works like a charm. Thanks a lot!