Signatur
Beschreibung
Mit Transform Feedback werden die Ausgaben des Vertex-Shaders (out-Variablen) direkt in Pufferobjekte geschrieben. Das nutzt man z. B. für GPU-Partikelsysteme, Physik-Simulationen oder zum Vorberechnen von Geometrie. Eine Aufnahme wird mit beginTransformFeedback() gestartet und mit endTransformFeedback() beendet.
Mit pauseTransformFeedback() lässt sich die Aufnahme zwischendurch anhalten, z. B. um Zeichenaufrufe mit einem anderen Programm oder ohne Aufzeichnung auszuführen, während das aktive Transform-Feedback-Objekt seinen Zustand und die Schreibposition in den Puffern behält. resumeTransformFeedback() setzt die Aufnahme genau an dieser Stelle fort: Neue Vertices werden hinter die bereits geschriebenen Daten angehängt.
Die Methode wirkt immer auf das aktuell mit bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf) gebundene Transform-Feedback-Objekt. Das beim Fortsetzen aktive Programm muss dasselbe sein, das beim Aufruf von beginTransformFeedback() aktiv war.
Beispiele
Aufnahme anhalten und fortsetzen
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2');
// Annahme: 'program' wurde mit gl.transformFeedbackVaryings(program, ['vPosition'], gl.SEPARATE_ATTRIBS)
// vor dem Linken konfiguriert, 'outBuffer' ist groß genug.
const tf = gl.createTransformFeedback();
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, outBuffer);
gl.useProgram(program);
gl.enable(gl.RASTERIZER_DISCARD);
gl.beginTransformFeedback(gl.POINTS);
gl.drawArrays(gl.POINTS, 0, 100); // Vertices 0–99 werden aufgezeichnet
gl.pauseTransformFeedback();
// ... hier könnten andere Operationen ohne Aufzeichnung stattfinden
gl.resumeTransformFeedback();
gl.drawArrays(gl.POINTS, 100, 100); // wird hinter die ersten 100 angehängt
gl.endTransformFeedback();
gl.disable(gl.RASTERIZER_DISCARD);
console.log(gl.getError() === gl.NO_ERROR);
Status vor dem Fortsetzen prüfen
const safeResume = (gl) => {
const active = gl.getParameter(gl.TRANSFORM_FEEDBACK_ACTIVE);
const paused = gl.getParameter(gl.TRANSFORM_FEEDBACK_PAUSED);
if (active && paused) {
gl.resumeTransformFeedback();
return true;
}
return false;
};
// Nach gl.beginTransformFeedback(...) und gl.pauseTransformFeedback():
console.log(safeResume(gl));
Fehlerfall: Fortsetzen ohne Pause
gl.beginTransformFeedback(gl.POINTS);
gl.resumeTransformFeedback(); // nicht pausiert -> Fehler
console.log(gl.getError() === gl.INVALID_OPERATION);
gl.endTransformFeedback();
// Wichtig · Fallstricke
- INVALID_OPERATION entsteht, wenn das gebundene Transform-Feedback-Objekt nicht aktiv oder nicht pausiert ist, oder wenn beim Fortsetzen ein anderes Programm aktiv ist als bei
beginTransformFeedback(). - Im pausierten Zustand darf man ein anderes Transform-Feedback-Objekt binden (
bindTransformFeedback) – vor dem Fortsetzen muss das ursprüngliche Objekt aber wieder gebunden sein. - Der Primitivtyp der Zeichenaufrufe nach dem Fortsetzen muss zum bei
beginTransformFeedback()angegebenen Modus passen, sonst gibt es ebenfallsINVALID_OPERATION. - Nur in WebGL 2 verfügbar (
getContext('webgl2')); in WebGL 1 gibt es kein Transform Feedback. Alle aktuellen Browser unterstützen WebGL 2, Safari seit Version 15.