Search code examples
opengldepth-buffer

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.


Solution

  • 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.