是否可以在一次传递中从多个视图渲染对象

时间:2014-07-31 12:15:09

标签: opengl depth-buffer

我需要从多个视图渲染场景的深度,是否可以在单个渲染过程中进行渲染?

深度值可以保存在任何形式的2D纹理中。

3 个答案:

答案 0 :(得分:4)

这应该是有点创造力的。通过在opengl 3.2上引入ARB_viewport_arrayglViewportIndexedglDepthRangeIndexed),可以指定多个视口(最多可以指定六个视口,因此可以在一次传递中呈现立方体贴图) 。在geometry shader的帮助下,可以复制几何体以定位特定的视口/图层,另请参阅gl_ViewportIndexgl_Layer。根据您完全想要渲染的方式,即分屏或分离缓冲区,您可能需要有条件地将片段输出到不同的缓冲区或相应的屏幕的不同部分。另请参阅Rendering to cube map

答案 1 :(得分:1)

您可以使用几何着色器,并将视口分解为单独的子窗口。例如,您可以从4个不同的视图渲染场景,并且您将每个视图渲染为当前视口的1/4(例如,视口的左上角四分之一将是一个"视图&#34 ;场景)。

您将拥有一个直通顶点着色器,然后将4个模型 - 视图 - 投影矩阵作为制服提供给几何着色器。几何着色器将三角形作为输入,对于每个输入三角形,输出4个三角形(12个顶点):

#version 150 core
uniform mat4 MVP_TopLeft;
uniform mat4 MVP_TopRight;
uniform mat4 MVP_BottomLeft;
uniform mat4 MVP_BottomRight;
layout(triangles) in;
layout(GL_TRIANGLES​, max_vertices = 12​) out;
out int SubWindowID;
void main(void) {
    SubWindowID = 0;
    for (int i = 0; i < 3; i++) {
        gl_Position = MVP_TopLeft*gl_in[i].gl_Position;
        //Shift the coordinates into the mini-window
        gl_Position.x = (0.5*gl_Position.x - 0.5);
        gl_Position.y = (0.5*gl_Position.y + 0.5);
        EmitVertex();
    }
    EmitPrimitive();

    SubWindowID = 1;
    for (int i = 0; i < 3; i++) {
        gl_Position = MVP_TopRight*gl_in[i].gl_Position;
        //Shift the coordinates into the mini-window
        gl_Position.x = (0.5*gl_Position.x + 0.5);
        gl_Position.y = (0.5*gl_Position.y + 0.5);
        EmitVertex();
    }
    EmitPrimitive();

    SubWindowID = 2;
    for (int i = 0; i < 3; i++) {
        gl_Position = MVP_BottomLeft*gl_in[i].gl_Position;
        //Shift the coordinates into the mini-window
        gl_Position.x = (0.5*gl_Position.x - 0.5);
        gl_Position.y = (0.5*gl_Position.y - 0.5);
        EmitVertex();
    }
    EmitPrimitive();

    SubWindowID = 3;
    for (int i = 0; i < 3; i++) {
        gl_Position = MVP_BottomRight*gl_in[i].gl_Position;
        //Shift the coordinates into the mini-window
        gl_Position.x = (0.5*gl_Position.x + 0.5);
        gl_Position.y = (0.5*gl_Position.y - 0.5);
        EmitVertex();
    }
    EmitPrimitive();
}

然后,在片段着色器中,您将在main函数上方声明in int SubWindowID;,并且该int将对应于正在绘制该片段的子窗口。

答案 2 :(得分:0)

由于渲染管道的工作方式,您所建议的是不可能的:

  • 您将一堆顶点发送到管道
  • 在顶点着色阶段,视频卡接收投影矩阵并根据投影矩阵均匀将每个顶点放在投影空间中的位置
  • 现在在投影空间中正确设置了顶点,并且会出现光栅化并出现碎片因此片段着色阶段开始
  • 片段写入深度缓冲区

你所建议的意思是第2阶段有两个输出而不是一个输出,这是不可能的。您可以向着色器发送场景中每个摄像机的投影矩阵,但在投影空间中只有1个出口顶点(顶点着色器最终结果是空间中的位置,而不是一组位置)。

相关问题