我需要从多个视图渲染场景的深度,是否可以在单个渲染过程中进行渲染?
深度值可以保存在任何形式的2D纹理中。
答案 0 :(得分:4)
这应该是有点创造力的。通过在opengl 3.2上引入ARB_viewport_array(glViewportIndexed,glDepthRangeIndexed),可以指定多个视口(最多可以指定六个视口,因此可以在一次传递中呈现立方体贴图) 。在geometry shader的帮助下,可以复制几何体以定位特定的视口/图层,另请参阅gl_ViewportIndex,gl_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个出口顶点(顶点着色器最终结果是空间中的位置,而不是一组位置)。