Signatur
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
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);
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}]`);
}
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`);
// Wichtig · Fallstricke
- Die Reihenfolge ist entscheidend:
transformFeedbackVaryings()wirkt erst nach dem nächstenlinkProgram(). Fragst du vor dem Linken ab, bekommst du veraltete Daten oder gar keine. - Ein Index außerhalb des gültigen Bereichs führt zu
nullund zum Fehlergl.INVALID_VALUE. Prüfe das mitgl.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
getProgramParameterzwingt 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.