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

WebGL2RenderingContext.getTransformFeedbackVarying()

Methode

Liefert ein <code>WebGLActiveInfo</code>-Objekt mit Name, Typ und Größe einer Varying-Variablen, die per Transform Feedback aus einem gelinkten Programm aufgezeichnet wird.

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

Signatur

WebGL2RenderingContext.prototype.getTransformFeedbackVarying(program, index)

Beschreibung

Mit getTransformFeedbackVarying() fragst du ab, welche Ausgabevariablen (Varyings) eines Shader-Programms beim Transform Feedback aufgezeichnet werden. Welche Varyings das sind, legst du vorher mit gl.transformFeedbackVaryings() fest. Die Einstellung greift aber erst nach gl.linkProgram().

Du bekommst ein WebGLActiveInfo-Objekt mit drei Eigenschaften zurück: name (Name der Variablen im GLSL-Code), type (GL-Typkonstante wie gl.FLOAT_VEC3) und size (Anzahl der Elemente, bei Arrays größer als 1). Damit kannst du zur Laufzeit prüfen, ob die Aufzeichnung wie erwartet eingerichtet ist, und die passende Puffergröße berechnen.

Wie viele Varyings es insgesamt gibt, liefert gl.getProgramParameter(program, gl.TRANSFORM_FEEDBACK_VARYINGS). Gültige Indizes laufen von 0 bis zu dieser Anzahl minus 1. Typische Einsatzgebiete sind Partikelsysteme auf der GPU, das Debuggen von Transform-Feedback-Setups und generische Werkzeuge, die Shader-Programme untersuchen.

Parameter

Name Typ Default Beschreibung
$program Pflicht WebGLProgram Das gelinkte Shader-Programm, für das vorher transformFeedbackVaryings() aufgerufen wurde.
$index Pflicht GLuint (number) Index der Varying-Variablen, von 0 bis TRANSFORM_FEEDBACK_VARYINGS - 1.

Rückgabewert

Typ
WebGLActiveInfo | null
Beschreibung
Ein WebGLActiveInfo-Objekt mit name, type und size. Bei einem ungültigen Index oder Programm gibt die Methode null zurück und setzt einen GL-Fehler (z. B. INVALID_VALUE).

Beispiele

Varyings festlegen und abfragen

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

const vsSource = `#version 300 es
in vec3 aPos;
out vec3 vNewPos;
out float vLife;
void main() {
  vNewPos = aPos + vec3(0.0, 0.01, 0.0);
  vLife = 1.0;
  gl_Position = vec4(aPos, 1.0);
}`;

const fsSource = `#version 300 es
precision mediump float;
out vec4 color;
void main() { color = vec4(1.0); }`;

const compile = (type, src) => {
  const s = gl.createShader(type);
  gl.shaderSource(s, src);
  gl.compileShader(s);
  return s;
};

const program = gl.createProgram();
gl.attachShader(program, compile(gl.VERTEX_SHADER, vsSource));
gl.attachShader(program, compile(gl.FRAGMENT_SHADER, fsSource));

// Muss VOR linkProgram aufgerufen werden
gl.transformFeedbackVaryings(program, ['vNewPos', 'vLife'], gl.INTERLEAVED_ATTRIBS);
gl.linkProgram(program);

const info = gl.getTransformFeedbackVarying(program, 0);
console.log(info.name, info.type === gl.FLOAT_VEC3, info.size);
vNewPos true 1

Alle Varyings auflisten

const typeNames = {
  [gl.FLOAT]: 'float',
  [gl.FLOAT_VEC2]: 'vec2',
  [gl.FLOAT_VEC3]: 'vec3',
  [gl.FLOAT_VEC4]: 'vec4'
};

const count = gl.getProgramParameter(program, gl.TRANSFORM_FEEDBACK_VARYINGS);

for (let i = 0; i < count; i++) {
  const { name, type, size } = gl.getTransformFeedbackVarying(program, i);
  console.log(`${i}: ${typeNames[type] ?? type} ${name}[${size}]`);
}
0: vec3 vNewPos[1] 1: float vLife[1]

Puffergröße für Partikel berechnen

const componentCount = {
  [gl.FLOAT]: 1,
  [gl.FLOAT_VEC2]: 2,
  [gl.FLOAT_VEC3]: 3,
  [gl.FLOAT_VEC4]: 4
};

const varyingCount = gl.getProgramParameter(program, gl.TRANSFORM_FEEDBACK_VARYINGS);
let floatsPerVertex = 0;
for (let i = 0; i < varyingCount; i++) {
  const info = gl.getTransformFeedbackVarying(program, i);
  floatsPerVertex += componentCount[info.type] * info.size;
}

const particleCount = 10000;
const byteSize = floatsPerVertex * 4 * particleCount;

const tfBuffer = gl.createBuffer();
gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer);
gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, byteSize, gl.DYNAMIC_COPY);
console.log(`${floatsPerVertex} Floats pro Vertex, ${byteSize} Bytes`);
4 Floats pro Vertex, 160000 Bytes

// Wichtig · Fallstricke

  • Die Reihenfolge ist entscheidend: transformFeedbackVaryings() wirkt erst nach dem nächsten linkProgram(). Fragst du vor dem Linken ab, bekommst du veraltete Daten oder gar keine.
  • Ein Index außerhalb des gültigen Bereichs führt zu null und zum Fehler gl.INVALID_VALUE. Prüfe das mit gl.getError().
  • Wenn ein angegebenes Varying im Shader fehlt oder der Compiler es wegoptimiert hat, schlägt das Linken fehl. Kontrolliere deshalb gl.getProgramParameter(program, gl.LINK_STATUS).
  • Die Methode gibt es nur im WebGL2RenderingContext. Ein WebGL‑1-Kontext (getContext('webgl')) hat sie nicht. WebGL 2 läuft in allen aktuellen Browsern, in Safari ab Version 15.
  • Wie Mehrfachaufrufe von getProgramParameter zwingt auch diese Methode den Treiber zu einer Synchronisation. Frag die Informationen deshalb einmal ab und speichere sie zwischen, statt sie in jedem Frame neu zu holen.