我认为我不太了解 Unity 渲染引擎。
我使用 RenderTexture 生成屏幕截图(我需要稍后管理它):
screenshotRenderTexture = new RenderTexture(screenshot.width, screenshot.height, depthBufferBits, RenderTextureFormat.Default);
screenshotRenderTexture.Create();
RenderTexture currentRenderTexture = RenderTexture.active;
RenderTexture.active = screenshotRenderTexture;
Camera[] cams = Camera.allCameras;
System.Array.Sort(
cams,
delegate(Camera cam1, Camera cam2)
{
// It's easier than write float to int conversion that won't floor
// depth deltas under 1 to zero and will correctly work with NaNs
if (cam1.depth < cam2.depth)
return -1;
else if (cam1.depth > cam2.depth)
return 1;
else return 0;
}
);
foreach(Camera cam in cams)
{
cam.targetTexture = screenshotRenderTexture;
cam.Render();
cam.targetTexture = null;
}
screenshot.ReadPixels(new Rect(0, 0, textureWidth, textureHeight), 0, 0);
screenshot.Apply();
RenderTexture.active = currentRenderTexture;
但是,如果 depthBufferBits 为 0,则渲染结果会出现各种 z-buffer 错误(以错误的顺序渲染的东西)。
我理解一般意义上的深度缓冲区是什么。但是,我不明白的是——如果使用 RenderTexture 来组合单个相机的渲染结果,为什么需要深度缓冲区?这种抽象是如何工作的,究竟是相机自己创建图像,然后将其提供给 RenderTexture,还是相机使用 RenderTexture 的深度缓冲区?似乎是后者,因为我遇到了错误(错误顺序的东西都是用同一个相机渲染的,所以问题是在一个相机内订购东西,而不是在不同相机之间订购东西),但同时有时它与这些抽象如何在 C# 级别上构建的常识相矛盾。
最后,我能以某种方式使用默认深度缓冲区,用于在这个上进行正常渲染吗?因为移动设备上每像素 16 位是非常痛苦的。
更新:
这是我试图做的事情:
screenshotRenderTexture = new RenderTexture(
screenshot.width,
screenshot.height,
0,
RenderTextureFormat.Default
);
screenshotRenderTexture.Create();
RenderBuffer currentColorBuffer = Graphics.activeColorBuffer;
Graphics.SetRenderTarget(screenshotRenderTexture.colorBuffer, Graphics.activeDepthBuffer);
yield return new WaitForEndOfFrame();
Graphics.SetRenderTarget(currentColorBuffer, Graphics.activeDepthBuffer);
这就是我得到的:
SetRenderTarget can only mix color & depth buffers from RenderTextures. You're trying to set depth buffer from the screen.
UnityEngine.Graphics:SetRenderTarget(RenderBuffer, RenderBuffer)
<ScreenshotTaking>c__Iterator21:MoveNext() (at Assets/Scripts/Managers/ScreenshotManager.cs:126)
为什么它不能混合来自屏幕的深度缓冲区和来自 RenderTexture 的颜色缓冲区?