OVR_multiview2
WebGL working group (public_webgl 'at' khronos.org)
Olli Etuaho, NVIDIA
Mingyu Hu, Microsoft
Members of the WebGL working group
 Last modified date: November 26, 2019
          Revision: 17
WebGL extension #36
Written against the WebGL API 2.0 specification.
This extension exposes the OVR_multiview2 functionality to WebGL.
The following WebGL-specific behavioral changes apply:
framebufferTextureMultiviewOVR with a non-null texture parameter that does not identify a 2D array texture generates an INVALID_OPERATION error.
      baseViewIndex and numViews can result in an error only if the texture parameter is non-null.
      baseViewIndex is not the same for all framebuffer attachment points where
        the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is not NONE the
        framebuffer is considered incomplete. Calling checkFramebufferStatus for a
        framebuffer in this state returns FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR.
        Other rules for framebuffer completeness from the OVR_multiview specification also apply.
        #extension GL_OVR_multiview2 directive, as shown in the sample code, to use
        the extension in a shader.
        Likewise the shading language preprocessor #define GL_OVR_multiview2, will be defined to 1 if the extension is supported.
      #extension GL_OVR_multiview directive is not supported.
        The only supported shader extension string is GL_OVR_multiview2.
        Likewise the shading language preprocessor will not define GL_OVR_multiview,
        even if OVR_multiview2 is supported.
      gl_ViewID_OVR will always evaluate to zero.
      clear generates an INVALID_OPERATION error.
      INVALID_OPERATION error.
      Consult the above extension for documentation, issues and new functions and enumerants.
When this extension is enabled:
GL_OVR_multiview2 with an extension directive:
        gl_ViewID_OVR is a built-in input of the type uint.GL_OVR_multiview2 is defined as 1.
      
[Exposed=(Window,Worker), LegacyNoInterfaceObject]
interface OVR_multiview2 {
    const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR = 0x9630;
    const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR = 0x9632;
    const GLenum MAX_VIEWS_OVR = 0x9631;
    const GLenum FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR = 0x9633;
    undefined framebufferTextureMultiviewOVR(GLenum target, GLenum attachment, WebGLTexture? texture, GLint level, GLint baseViewIndex, GLsizei numViews);
};
  pname set to MAX_VIEWS_OVR returns the maximum number of views. The implementation must support at least 2 views.
      | pname | returned type | 
|---|---|
| MAX_VIEWS_OVR | GLint | 
pname parameter set to FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR returns the number of views of the framebuffer object attachment.
        Calling with the pname parameter set to FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR returns the base view index of the framebuffer object attachment.
        | pname | returned type | 
|---|---|
| FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR | GLsizei | 
| FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR | GLint | 
INVALID_OPERATION is generated by calling framebufferTextureMultiviewOVR with a texture parameter that does not identify a 2D array texture.
    INVALID_VALUE is generated by calling framebufferTextureMultiviewOVR with a non-null texture in the following cases:
      numViews is less than onenumViews is more than MAX_VIEWS_OVRbaseViewIndex + numViews is larger than the value of MAX_ARRAY_TEXTURE_LAYERSbaseViewIndex is negativeINVALID_FRAMEBUFFER_OPERATION is generated by commands that read from the framebuffer such as BlitFramebuffer, ReadPixels, CopyTexImage*, and CopyTexSubImage*, if the number of views in the current read framebuffer is greater than one.
    INVALID_OPERATION is generated by attempting to draw if the active program declares a number of views and the number of views in the draw framebuffer does not match the number of views declared in the active program.
    INVALID_OPERATION is generated by attempting to draw if the number of views in the current draw framebuffer is greater than one and the active program does not declare a number of views.
    INVALID_OPERATION is generated by attempting to draw if the number of views in the current draw framebuffer is greater than one and transform feedback is active and not paused.
    INVALID_OPERATION is generated by attempting to draw or calling clear if the number of views in the current draw framebuffer is greater than one and a timer query is active.
    
    var gl = document.createElement('canvas').getContext('webgl2');
    var ext = gl.getExtension('OVR_multiview2');
    var fb = gl.createFramebuffer();
    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb);
    var colorTex = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D_ARRAY, colorTex);
    gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, 512, 512, 2);
    ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
    var depthStencilTex = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D_ARRAY, depthStencilTex);
    gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.DEPTH32F_STENCIL8, 512, 512, 2);
    ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, depthStencilTex, 0, 0, 2);
    gl.drawElements(...);  // draw will be broadcasted to the layers of colorTex and depthStencilTex.
    
  
    
    #version 300 es
    #extension GL_OVR_multiview2 : require
    precision mediump float;
    layout (num_views = 2) in;
    in vec4 inPos;
    uniform mat4 u_viewMatrices[2];
    void main() {
      gl_Position = u_viewMatrices[gl_ViewID_OVR] * inPos;
    }
    
  Revision 1, 2016/11/11
Revision 2, 2016/11/25
Revision 3, 2016/12/21
Revision 4, 2017/01/12
Revision 5, 2017/03/10
Revision 6, 2017/05/19
Revision 7, 2017/05/23
Revision 8, 2017/07/21
Revision 9, 2017/08/08
Revision 10, 2017/08/17
Revision 11, 2017/10/26
Revision 12, 2018/01/03
Revision 13, 2018/07/26
Revision 14, 2019/03/06
Revision 15, 2019/04/25
Revision 16, 2019/07/24
Revision 17, 2019/11/26