Start · Sprachen · JavaScript · Referenz · WebGL2RenderingContext.getInternalformatParameter()

WebGL2RenderingContext.getInternalformatParameter()

Methode

Fragt ab, welche Multisample-Stufen (Sample-Anzahlen) die WebGL-2-Implementierung für ein bestimmtes internes Renderbuffer-Format unterstützt.

seit JavaScript WebGL 2 – Baseline: alle modernen Browser (seit 20 Kategorie: webapi

Signatur

WebGL2RenderingContext.prototype.getInternalformatParameter(target, internalformat, pname)

Beschreibung

Mit getInternalformatParameter() kannst du herausfinden, welche Möglichkeiten die jeweilige Grafik-Implementierung für ein bestimmtes internes Format bietet. In WebGL 2 lässt sich damit in der Praxis nur eines abfragen: die unterstützten Sample-Anzahlen für Multisample-Renderbuffer (gl.SAMPLES).

Gebraucht wird das vor allem für Multisample-Anti-Aliasing (MSAA) beim Offscreen-Rendering: Bevor du mit renderbufferStorageMultisample() einen Renderbuffer anlegst, prüfst du, welche Sample-Werte für das gewünschte Format (z. B. gl.RGBA8, gl.DEPTH24_STENCIL8 oder gl.RGBA16F) überhaupt gültig sind. Der Rückgabewert ist ein Int32Array, absteigend sortiert – das erste Element ist also die höchste mögliche Sample-Anzahl.

Die Werte hängen von GPU, Treiber und Browser ab. Sie können auch zwischen Formaten stark voneinander abweichen: Gleitkomma-Formate unterstützen oft weniger Samples als RGBA8, und Integer-Formate wie RGBA8UI liefern meist ein leeres Array, weil sie kein Multisampling erlauben.

Parameter

Name Typ Default Beschreibung
$target Pflicht GLenum Ziel der Abfrage. Muss gl.RENDERBUFFER sein.
$internalformat Pflicht GLenum Internes Format, das rendern kann (color-renderable, depth-renderable oder stencil-renderable), z. B. gl.RGBA8, gl.RGB565, gl.DEPTH_COMPONENT24, gl.DEPTH24_STENCIL8, gl.R8. Gleitkomma-Formate wie gl.RGBA16F sind nur nutzbar, wenn die Erweiterung EXT_color_buffer_float aktiv ist.
$pname Pflicht GLenum Welche Information abgefragt wird. Möglich ist nur gl.SAMPLES.

Rückgabewert

Typ
Int32Array | null
Beschreibung
Bei gl.SAMPLES ein Int32Array mit den unterstützten Sample-Anzahlen, absteigend sortiert (z. B. [8, 4, 2]). Unterstützt ein Format kein Multisampling, ist das Array leer. Bei ungültigen Argumenten gibt die Methode null zurück und setzt einen GL-Fehler (INVALID_ENUM).

Beispiele

Unterstützte Sample-Anzahlen für RGBA8 abfragen

const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2');

if (!gl) {
  console.log('WebGL 2 wird nicht unterstützt');
} else {
  const samples = gl.getInternalformatParameter(
    gl.RENDERBUFFER,
    gl.RGBA8,
    gl.SAMPLES
  );
  console.log(samples);
  console.log('Maximum:', samples[0]);
}
Int32Array(3) [8, 4, 2] Maximum: 8

MSAA-Renderbuffer mit bester unterstützter Qualität anlegen

const gl = document.querySelector('canvas').getContext('webgl2');

// Wählt die höchste unterstützte Sample-Anzahl, höchstens aber `wanted`
const pickSamples = (format, wanted = 4) => {
  const list = gl.getInternalformatParameter(gl.RENDERBUFFER, format, gl.SAMPLES);
  if (!list || list.length === 0) return 0; // kein Multisampling möglich
  return list.find((s) => s <= wanted) ?? 0;
};

const width = gl.drawingBufferWidth;
const height = gl.drawingBufferHeight;
const samples = pickSamples(gl.RGBA8, 4);

const fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);

const colorRb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, colorRb);
gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, gl.RGBA8, width, height);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRb);

console.log('Verwendete Samples:', samples);
console.log(gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE);
Verwendete Samples: 4 true

Mehrere Formate vergleichen (inkl. Float-Erweiterung)

const gl = document.createElement('canvas').getContext('webgl2');

// Float-Formate sind erst nach Aktivierung der Erweiterung renderbar
const hasFloat = gl.getExtension('EXT_color_buffer_float') !== null;

const formats = {
  RGBA8: gl.RGBA8,
  DEPTH24_STENCIL8: gl.DEPTH24_STENCIL8,
  RGBA8UI: gl.RGBA8UI,
  ...(hasFloat && { RGBA16F: gl.RGBA16F })
};

for (const [name, format] of Object.entries(formats)) {
  const samples = gl.getInternalformatParameter(gl.RENDERBUFFER, format, gl.SAMPLES);
  console.log(name, Array.from(samples ?? []));
}
RGBA8 [8, 4, 2] DEPTH24_STENCIL8 [8, 4, 2] RGBA8UI [] RGBA16F [8, 4, 2]

// Wichtig · Fallstricke

  • Nur WebGL 2: Die Methode gibt es ausschließlich auf WebGL2RenderingContext. Ein WebGL-1-Kontext (getContext('webgl')) hat sie nicht, und dort gibt es auch kein renderbufferStorageMultisample().
  • Einzige gültige Kombination: target muss gl.RENDERBUFFER und pname muss gl.SAMPLES sein. Andere Werte führen zu INVALID_ENUM und null. Nach Fehlern kannst du mit gl.getError() suchen.
  • Ergebnisse unterscheiden sich je Gerät: Verlass dich nicht auf feste Werte wie 8 oder 4. Frag sie immer zur Laufzeit ab. Auf Mobilgeräten ist das Maximum oft 4. Die globale Obergrenze liefert gl.getParameter(gl.MAX_SAMPLES), aber je nach Format kann der tatsächliche Wert darunter liegen.
  • Leeres Array: Integer-Formate (RGBA8UI, R32I …) unterstützen kein Multisampling. Rechne mit einem leeren Array und nutze dann 0 Samples.
  • Float-Formate: Ohne EXT_color_buffer_float sind RGBA16F/RGBA32F nicht color-renderable. Bei RGBA32F wird Multisampling oft gar nicht unterstützt.
  • Fingerprinting: Einige Browser mit Datenschutz-Fokus runden die Werte oder vereinheitlichen sie. Behandle sie deshalb nur als Hinweis und prüfe den Framebuffer zusätzlich mit checkFramebufferStatus().