Start · Sprachen · JavaScript · Referenz · WebGLShaderPrecisionFormat.rangeMin

WebGLShaderPrecisionFormat.rangeMin

Eigenschaft

Schreibgeschützte Ganzzahl: Basis-2-Logarithmus des Betrags des kleinsten (negativsten) Wertes, den ein Shader-Datentyp darstellen kann.

seit JavaScript WebGL 1.0 – Baseline: alle modernen Browser Kategorie: webapi

Signatur

WebGLShaderPrecisionFormat.rangeMin

Beschreibung

Die schreibgeschützte Eigenschaft rangeMin eines WebGLShaderPrecisionFormat-Objekts sagt, wie weit der Wertebereich eines Shader-Datentyps (z. B. mediump float im Fragment-Shader) in den negativen Bereich reicht. Der Wert ist der Basis-2-Logarithmus des Betrags des kleinsten darstellbaren Wertes. Bei rangeMin = 127 reicht der Bereich also bis etwa -2^127.

Das Objekt bekommt man über gl.getShaderPrecisionFormat(shaderType, precisionType). Zusammen mit rangeMax und precision lässt sich damit prüfen, ob die GPU zum Beispiel highp im Fragment-Shader unterstützt oder ob mediump für Berechnungen mit großen Werten reicht. Das ist gerade auf Mobilgeräten wichtig.

Bei Gleitkommatypen entspricht rangeMin ungefähr dem Exponentenbereich: 127 bei IEEE-754-Single-Precision (highp float) und oft 15 bei Half-Precision (mediump float). Bei Ganzzahltypen (LOW_INT, MEDIUM_INT, HIGH_INT) gibt der Wert die Bitbreite des Bereichs an. Bei 32-Bit-Integern ist rangeMin zum Beispiel 31, der Bereich reicht dann also bis -2^31.

Rückgabewert

Typ
number
Beschreibung
Ganzzahl (GLint): log2(|kleinster darstellbarer Wert|). Ist ein Präzisionstyp nicht verfügbar, ist der Wert 0.

Beispiele

Wertebereich von highp float im Fragment-Shader auslesen

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

const fmt = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT);
console.log('rangeMin:', fmt.rangeMin);
console.log('rangeMax:', fmt.rangeMax);
console.log('precision:', fmt.precision);
rangeMin: 127 rangeMax: 127 precision: 23

highp-Unterstützung prüfen und Shader-Präzision wählen

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

const supportsHighp = () => {
  const fmt = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT);
  // Ist highp nicht vorhanden, sind alle Felder 0
  return fmt.rangeMin > 0 && fmt.precision > 0;
};

const precision = supportsHighp() ? 'highp' : 'mediump';
const fragmentSrc = `precision ${precision} float;
void main() { gl_FragColor = vec4(1.0); }`;
console.log('Verwende:', precision);
Verwende: highp

Übersicht aller Präzisionstypen als Tabelle

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

const shaders = { VERTEX: gl.VERTEX_SHADER, FRAGMENT: gl.FRAGMENT_SHADER };
const types = ['LOW_FLOAT', 'MEDIUM_FLOAT', 'HIGH_FLOAT', 'LOW_INT', 'MEDIUM_INT', 'HIGH_INT'];

const rows = [];
for (const [sName, sType] of Object.entries(shaders)) {
  for (const t of types) {
    const { rangeMin, rangeMax, precision } = gl.getShaderPrecisionFormat(sType, gl[t]);
    // Ungefährer kleinster Wert: -(2^rangeMin)
    rows.push({ shader: sName, typ: t, rangeMin, rangeMax, precision, min: -(2 ** rangeMin) });
  }
}
console.table(rows);
Tabelle mit z. B. FRAGMENT / MEDIUM_FLOAT: rangeMin 15, rangeMax 15, precision 10

// Wichtig · Fallstricke

  • Logarithmus, kein echter Wert: rangeMin ist ein Exponent. Den ungefähren kleinsten Wert bekommt man mit -(2 ** rangeMin). Der Wert ist positiv, obwohl er die untere, also negative Grenze beschreibt.
  • Hardwareabhängig: Die Werte kommen vom Treiber und von der GPU. Desktop-GPUs melden oft auch bei LOW_FLOAT und MEDIUM_FLOAT dieselben Werte wie bei highp (127/127/23). Mobile GPUs melden dagegen häufig echte Half-Precision-Werte (15/15/10).
  • Nicht unterstützt: Fehlt ein Präzisionstyp, zum Beispiel highp im Fragment-Shader unter WebGL 1 auf alter Hardware, sind alle drei Felder 0.
  • Fingerprinting: Die Werte verraten Details über die Hardware und werden für Browser-Fingerprinting genutzt. Datenschutzfreundliche Browser können Standardwerte zurückgeben.
  • Kompatibilität: Gibt es in WebGL 1 und WebGL 2 (WebGL2RenderingContext) in allen modernen Browsern. Ist der Kontext verloren, gibt getShaderPrecisionFormat null zurück. Vor dem Zugriff also prüfen.