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 );
|