Signatur
Beschreibung
Die Methode framebufferTextureMultiviewOVR() gehört zur WebGL-2-Erweiterung OVR_multiview2. Sie verbindet einen zusammenhängenden Bereich von Ebenen (Layern) einer TEXTURE_2D_ARRAY mit einem Anhangspunkt des gerade gebundenen Framebuffers. Jede Ebene entspricht dabei einer Ansicht (View).
Multiview wird vor allem für VR/AR-Stereo-Rendering (z. B. mit WebXR) eingesetzt: Statt die Szene für das linke und das rechte Auge zweimal zu zeichnen, genügt ein Draw-Call. Im Vertex-Shader steht die eingebaute Variable gl_ViewID_OVR zur Verfügung, über die man pro Ansicht eine eigene View-/Projektionsmatrix auswählt. Das spart CPU-Zeit und Treiber-Overhead erheblich.
Damit das funktioniert, muss der Shader in GLSL ES 3.00 geschrieben sein, die Direktive #extension GL_OVR_multiview2 : require enthalten und die Anzahl der Ansichten mit layout(num_views = N) in; festlegen. N muss mit dem Parameter numViews übereinstimmen.
Um die Erweiterung zu nutzen, ruft man zunächst gl.getExtension("OVR_multiview2") auf einem WebGL2RenderingContext auf. Liefert der Aufruf null, wird Multiview auf dem Gerät nicht unterstützt und man muss auf klassisches Rendern in zwei Durchgängen zurückfallen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $target Pflicht | GLenum | Framebuffer-Ziel: gl.FRAMEBUFFER, gl.DRAW_FRAMEBUFFER oder gl.READ_FRAMEBUFFER. |
|
| $attachment Pflicht | GLenum | Anhangspunkt, z. B. gl.COLOR_ATTACHMENT0 … gl.COLOR_ATTACHMENTn, gl.DEPTH_ATTACHMENT, gl.STENCIL_ATTACHMENT oder gl.DEPTH_STENCIL_ATTACHMENT. |
|
| $texture Pflicht | WebGLTexture | null | Eine Textur vom Typ TEXTURE_2D_ARRAY. Mit null wird ein bestehender Anhang entfernt. |
|
| $level Pflicht | GLint | Mipmap-Stufe der Textur, die angehängt wird (meist 0). |
|
| $baseViewIndex Pflicht | GLint | Index der ersten Array-Ebene, die als Ansicht 0 verwendet wird. | |
| $numViews Pflicht | GLsizei | Anzahl der Ansichten (Ebenen) ab baseViewIndex. Muss zwischen 1 und ext.MAX_VIEWS_OVR liegen und zu num_views im Shader passen. |
Rückgabewert
gl.getError() gemeldet.Beispiele
Stereo-Framebuffer mit zwei Ansichten einrichten
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl2');
const ext = gl.getExtension('OVR_multiview2');
if (!ext) {
throw new Error('OVR_multiview2 wird nicht unterstützt');
}
const width = 1024;
const height = 1024;
const views = 2; // linkes + rechtes Auge
// Farb-Textur als 2D-Array mit zwei Ebenen
const colorTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D_ARRAY, colorTex);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
// Tiefen-Textur ebenfalls als 2D-Array
const depthTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D_ARRAY, depthTex);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.DEPTH_COMPONENT24, width, height, views);
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb);
ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, depthTex, 0, 0, views);
const status = gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER);
console.log(status === gl.FRAMEBUFFER_COMPLETE ? 'Framebuffer bereit' : `Unvollständig: 0x${status.toString(16)}`);
Passender Vertex-Shader mit gl_ViewID_OVR
const vertexSource = `#version 300 es
#extension GL_OVR_multiview2 : require
layout(num_views = 2) in;
uniform mat4 u_viewProj[2];
uniform mat4 u_model;
in vec4 a_position;
void main() {
// gl_ViewID_OVR ist 0 für das linke, 1 für das rechte Auge
gl_Position = u_viewProj[gl_ViewID_OVR] * u_model * a_position;
}`;
const shader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(shader, vertexSource);
gl.compileShader(shader);
console.log(gl.getShaderParameter(shader, gl.COMPILE_STATUS));
Grenzen prüfen und Anhang wieder lösen
const maxViews = gl.getParameter(ext.MAX_VIEWS_OVR);
console.log(`Maximal unterstützte Ansichten: ${maxViews}`);
// Anhang entfernen, z. B. beim Aufräumen
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb);
ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, null, 0, 0, 1);
gl.deleteTexture(colorTex);
gl.deleteFramebuffer(fb);