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()
 {
 
 RenderTexture depthRT = RenderTexture.GetTemporary(Screen.width, Screen.height, 0, depthTarget.format);
 depthRT.filterMode = FilterMode.Point;
 
 Graphics.Blit(Shader.GetGlobalTexture("_CameraDepthTexture"), depthRT);
 
 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
 );
 
 |