Dual-Eye Rendering with GL_EXT_multiview in GLSL
Rendering stereoscopic scenes for virtual and augmented reality
requires presenting slightly offset perspectives for each eye, a process
that traditionally doubles CPU draw calls and state changes. The
GL_EXT_multiview OpenGL extension solves this bottleneck by
allowing a single draw call to dispatch geometry simultaneously to
multiple render targets. By integrating with GLSL through dedicated
built-in variables and layout qualifiers, this extension shifts the
burden of multi-perspective duplication to the GPU hardware,
streamlining the stereoscopic rendering pipeline and significantly
lowering latency and CPU overhead.
The Problem with Traditional Dual-Eye Rendering
Conventional VR pipelines render a scene by executing two full rendering passes: one for the left eye and one for the right eye. This approach forces the CPU to prepare, record, and dispatch commands twice for every mesh, doubling uniform updates and driver validation overhead. While instanced rendering can batch these operations, it still incurs per-instance processing costs and can introduce pipeline synchronization delays.
How GL_EXT_multiview Solves the Overhead
GL_EXT_multiview enables the GPU to draw primitives to
multiple layers of a 2D texture array simultaneously within a single
draw call. Instead of binding separate framebuffers or dispatching
separate passes, the application binds a multiview framebuffer with two
layers. The graphics pipeline then broadcasts the geometry to both eye
targets, duplicating the work at the hardware level where view-dependent
differences occur.
Integration in GLSL
The extension exposes key mechanisms directly in GLSL shaders, primarily within the vertex shader:
View Count Declaration: Shaders declare the number of simultaneous views using an input layout qualifier. For stereo rendering, this is set to two views:
#extension GL_EXT_multiview : enable layout(num_views = 2) in;The
gl_ViewID_OVRInput: The driver injects an internal integer variable,gl_ViewID_OVR, which specifies the target view currently being processed (typically0for the left eye and1for the right eye).Per-View Transformations: Rather than relying on a single Model-View-Projection (MVP) matrix, the shader defines an array of matrices for the respective views:
uniform mat4 u_ViewProjection[2]; void main() { mat4 mvp = u_ViewProjection[gl_ViewID_OVR] * u_Model; gl_Position = mvp * vec4(a_Position, 1.0); }
Hardware Execution and Optimization
When GL_EXT_multiview is active, the GPU processes the
view separation intelligently:
- Single Pipeline Setup: Primitives are submitted
once. View-invariant operations (such as skinning, physics, or early
object-space transforms) can be computed once, while only the projection
and view transforms are evaluated per
gl_ViewID_OVR. - Hardware Geometry Routing: Modern GPUs route the resulting primitives to the corresponding layer of the render target array based on the view index. Fixed-function hardware handles viewport transformations, scissoring, and primitive clipping independently per view.
- Tile-Based Deferred Renderers (TBDR): On mobile VR architectures, multiview allows binning and tiling steps to occur once for both views, conserving memory bandwidth and avoiding redundant rasterizer state setup.
By eliminating redundant API commands on the CPU and parallelizing
stereoscopic projection on the GPU, GL_EXT_multiview serves
as a fundamental building block for low-latency, high-frame-rate
rendering in modern GLSL pipelines.