C# 为什么我需要depthBuffer来使用RenderTexture?

C# 为什么我需要depthBuffer来使用RenderTexture?,c#,camera,unity3d,render,depth-buffer,C#,Camera,Unity3d,Render,Depth Buffer,我认为我不太了解Unity渲染引擎 我使用RenderTexture生成屏幕截图(稍后我需要管理它): 下面是我得到的: SetRenderTarget can only mix color & depth buffers from RenderTextures. You're trying to set depth buffer from the screen. UnityEngine.Graphics:SetRenderTarget(RenderBuffer, RenderBuffe

我认为我不太了解Unity渲染引擎

我使用RenderTexture生成屏幕截图(稍后我需要管理它):

下面是我得到的:

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)
SetRenderTarget只能混合来自RenderTexture的颜色和深度缓冲区。您正在尝试从屏幕设置深度缓冲区。
图形:SetRenderTarget(RenderBuffer,RenderBuffer)
c__迭代器21:MoveNext()(位于Assets/Scripts/Managers/ScreenshotManager.cs:126)

为什么它不能混合来自屏幕的深度缓冲区和来自RenderTexture的颜色缓冲区?

我不太了解Unity,但我知道它们的基本层,如果它们可以映射,比如说D3D9、D3d10和OpenGL,那么它们的抽象必须使用一个公分母

在这种情况下,D3D10是最具限制性的,您不能在不同大小的渲染目标之间共享深度曲面。如果屏幕和渲染目标的大小都相同,则确实可以将唯一的深度缓冲区绑定到不同的渲染目标

从严格意义上讲,深度缓冲区不是必需的,正如您所观察到的,您可以在不使用深度缓冲区的情况下进行渲染,但结果只是按照发出绘制命令的顺序进行渲染。(draw call=D3D中的DrawPrimitive,或glDrawBuffers等)甚至可以保证规范在三角形级别上的顺序是一致的,即使图形卡非常平行,为了通过一次draw call的不同运行实现绘图的一致性,它们也会被拒绝并行发布原语

如果使用深度缓冲区,则恰好在以较低深度绘制的对象之后进行绘制调用的对象将覆盖这些闭合对象(在视图空间中)并给出错误结果,深度缓冲区有助于逐像素丢弃具有深度(在视图空间中)的对象的像素比之前在该像素处已渲染的内容更深,但深度更近

绑定深度缓冲区也有助于提高性能,因为如果一个块中的每个像素的最小深度为某个值,则基本体光栅化器在顶点缓冲区退出后会知道,基本体的整个部分将永远不会在该块上渲染,并会完全丢弃整个块。这称为早期Z剔除,对性能有很大帮助。因此,最好保持深度缓冲区堵塞

摄影机在低级图形学理论中没有概念,它只是由一个视图矩阵表示,该矩阵是应用于整个世界的逆变换,以将世界从世界空间移动到视图空间,作为任何单个顶点变换计算的一部分。这就是为什么在经典顶点着色器中,位置从对象空间(在顶点缓冲流中)获取,然后乘以对象矩阵变换,然后乘以视图矩阵变换,然后乘以投影矩阵变换,然后光栅化器通过“w”对所有内容进行分析,以使透视图分开

也就是说,通过利用这种管道行为,您可以“创建”摄影机的概念。Unity必须通过公开一个camera类来抽象所有这些。可能camera类甚至有一个“texture target”成员来解释从该摄影机渲染的存储位置

是的,渲染是直接对指定的渲染纹理进行的,没有中间前缓冲区或任何东西,渲染目标是硬件支持的功能,渲染结束时不需要复制

渲染目标本身是一个完整的配置,由于硬件多采样,它实际上可能绑定多个具有所需分辨率大小的缓冲区

有颜色缓冲区(例如MSAA4x中的4个RGBA曲面)、深度缓冲区(通常为固定点24位表示)和8位模具曲面。所有这些曲面都表示渲染目标配置,并且是渲染所必需的

我希望这有帮助

    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)