Start · Sprachen · JavaScript · Referenz · OVR_multiview2.framebufferTextureMultiviewOVR()

OVR_multiview2.framebufferTextureMultiviewOVR()

Methode

Hängt mehrere Ebenen einer 2D-Array-Textur als Multiview-Anhang an den aktuell gebundenen <code>WebGLFramebuffer</code>, damit ein einziger Draw-Call mehrere Ansichten gleichzeitig rendert.

seit JavaScript WebGL 2 mit Erweiterung OVR_multiview2 (Chrome/Edg Kategorie: webapi

Signatur

OVR_multiview2.framebufferTextureMultiviewOVR(target, attachment, texture, level, baseViewIndex, numViews)

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

Typ
undefined
Beschreibung
Kein Rückgabewert. Fehler werden über 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)}`);
Framebuffer bereit

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));
true

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);
Maximal unterstützte Ansichten: 4