抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Unity保存RenderTarget

使用Unity产出一些美术资产时,经常需要保存某个RenderTarget,最近发现用ReadPixels进行保存时,精度很差,只有8 bits,最后成功搞定了保存32 bits RenderTarget的方法,在此记录一下

屏幕截图

如果想要保存当前屏幕的渲染结果,可以直接调用

ScreenCapture.CaptureScreenshot(pngPath);

保存相机的RT

public Camera renderCamera;

void saveColor()
{
RenderTexture activeRenderTexture = RenderTexture.active;
RenderTexture cameraRenderTexture = new RenderTexture(renderCamera.pixelWidth, renderCamera.pixelHeight, 24);
renderCamera.targetTexture = cameraRenderTexture;
renderCamera.Render();
RenderTexture.active = cameraRenderTexture;

Texture2D cameraImage = new Texture2D(renderCamera.pixelWidth, renderCamera.pixelHeight, TextureFormat.RGBAFloat, false);
cameraImage.ReadPixels(new Rect(0, 0, cameraRenderTexture.width, cameraRenderTexture.height), 0, 0);
cameraImage.Apply();

Color[] colors = cameraImage.GetPixels();
byte[] cameraImageBytes = cameraImage.EncodeToTGA();
File.WriteAllBytes(Path.Combine(outputPath, "cameraImage.tga"), cameraImageBytes);

}

保存深度

public RenderTexture depthTarget;

void Start()
{
depthTarget = new RenderTexture(1024, 1024, 0, RenderTextureFormat.RHalf)
{
autoGenerateMips = false,
useMipMap = false,
filterMode = FilterMode.Point
};
depthTarget.Create();
Camera.main.depthTextureMode |= DepthTextureMode.Depth;
}

void SaveDepth()
{
// 创建一个临时RT
RenderTexture depthRT = RenderTexture.GetTemporary(Screen.width, Screen.height, 0, depthTarget.format);
depthRT.filterMode = FilterMode.Point;
// 将GPU的深度贴图Blit到临时RT上
Graphics.Blit(Shader.GetGlobalTexture("_CameraDepthTexture"), depthRT);
// 将临时RT的像素保存到Color数组
Texture2D depthTexture = new Texture2D(depthRT.width, depthRT.height, TextureFormat.RFloat, false);
RenderTexture.active = depthRT;
depthTexture.ReadPixels(new Rect(0, 0, depthRT.width, depthRT.height), 0, 0);
depthTexture.Apply();
Color[] pixels = depthTexture.GetPixels();
RenderTexture.active = null;
// 编码、写贴图
byte[] bytes = depthTexture.EncodeToPNG();
string filename = Path.Combine(outputPath, "depth.png");
File.WriteAllBytes(filename, bytes);
}

更高精度的RT

我发现在保存相机RT时,每个通道的精度仅仅是8 bits,将这些通道乘以255.0f,就非常接近整数了

这其实是因为cameraRenderTexture的默认格式是ARGB32,每个通道仅8 bits,我只需要在其创建时设置一个更高精度的格式,比如ARGBFloat,每个通道32 bits,精度就大大提高了

RenderTexture cameraRenderTexture = new RenderTexture(renderCamera.pixelWidth, 
renderCamera.pixelHeight, 24,
+RenderTextureFormat.ARGBFloat
);

评论