shapeare
shapeare

Reputation: 4233

Is it possible to render an object from multiple views in a single pass

I need to render the depth of a scene from multiple views, is it possible to do it in a single rendering pass?

The depth value could be saved in any form of 2D texture.

Upvotes: 0

Views: 2285

Answers (3)

Jon Simpkins
Jon Simpkins

Reputation: 152

You might be able to do it with a geometry shader, and by breaking up the viewport into separate sub-windows. For example, you could render the scene from 4 different views, and you'll render each view as 1/4 of the current viewport (e.g. the top-left quarter of the viewport will be one "view" of the scene).

You would have a pass-through vertex shader, and then have the 4 model-view-projection matrices given to the geometry shader as uniforms. The geometry shader would take triangles as input, and for each input triangle, output 4 triangles (12 vertices):

#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();
}

Then, in the fragment shader, you would have in int SubWindowID; declared above the main function, and that int would correspond to which sub-window that fragment was being drawn in.

Upvotes: 1

Lawrence Kok
Lawrence Kok

Reputation: 1598

This should be possible with a bit of creativity. With the introduction of ARB_viewport_array (glViewportIndexed, glDepthRangeIndexed) on opengl 3.2 it has been possible to specify multiple viewports (up to six to be exact so cubemaps could be rendered in a single pass). With the help of a geometry shader the geometry can be duplicated to target specific viewports/layers, see also gl_ViewportIndex, gl_Layer​. Depending on how you exactly want to render i.e. split-screen or separated buffers you might need to conditionally output the fragments to different buffers, or different portions of the screen accordingly. See also Rendering to cube map

Upvotes: 4

MichaelCMS
MichaelCMS

Reputation: 4763

What you are suggesting is not possible because of the way the rendering pipeline works :

  • you send a bunch of vertexes to the pipeline
  • during vertex shading phase, the video card takes in the projection Matrix and puts each vertex at the position in projection space according to the projection matrix uniform
  • with the vertices now properly set in the projection space rasterization occurs and fragments appear thus fragment shading phase starts
  • fragments write in the depth buffer

What you are suggesting would mean for phase 2 to have two outputs instead of one, which is not possible. You will can send to the shader a projection matrix for each camera in your scene, but you will only have 1 exit vertex in projection space (vertex shader end result is a position in space, not a set of positions).

Upvotes: -1

Related Questions