TransformFeedback rendering pipeline

  • Webglsamples.org/WebGL2Sampl…
  • vs-transform
#version 300 es
#define POSITION_LOCATION 0

precision highp float;
precision highp int;

uniform mat4 MVP;
layout(location = POSITION_LOCATION) in vec4 position;

out vec4 v_color;

void main()
{
    gl_Position = MVP * position;
    v_color = vec4(clamp(vec2(position), 0.0.1.0), 0.0.1.0);
}
Copy the code
  • fs-transform
#version 300 es
precision highp float;
precision highp int;

in vec4 v_color;
out vec4 color;

void main()
{
    color = v_color;
}
Copy the code
  • vs-feedback
#version 300 es
#define POSITION_LOCATION 0
#define COLOR_POSITION 3

precision highp float;
precision highp int;

layout(location = POSITION_LOCATION) in vec4 position;
layout(location = COLOR_POSITION) in vec4 color;

out vec4 v_color;

void main()
{
    gl_Position = position;
    v_color = color;
}
Copy the code
  • fs-feedback
#version 300 es
precision highp float;
precision highp int;

in vec4 v_color;

out vec4 color;

void main()
{
    color = v_color;
}
Copy the code
  • Two Program statement: programTransform programFeedback
  • Notice the difference in how the two programs are declared
var programTransform = (function(gl, vertexShaderSourceTransform, fragmentShaderSourceTransform) {
    function createShader(gl, source, type) {
        var shader = gl.createShader(type);
        gl.shaderSource(shader, source);
        gl.compileShader(shader);
        return shader;
    }
    //
    var vshaderTransform = createShader(gl, vertexShaderSourceTransform, gl.VERTEX_SHADER);
    var fshaderTransform = createShader(gl, fragmentShaderSourceTransform, gl.FRAGMENT_SHADER);

    var programTransform = gl.createProgram();
    gl.attachShader(programTransform, vshaderTransform);
    gl.deleteShader(vshaderTransform);
    gl.attachShader(programTransform, fshaderTransform);
    gl.deleteShader(fshaderTransform);

    // Different from ordinary Program
    var varyings = ['gl_Position'.'v_color']; //
    gl.transformFeedbackVaryings(programTransform, varyings, gl.SEPARATE_ATTRIBS); 
    gl.linkProgram(programTransform);

    return programTransform;
})(gl, getShaderSource('vs-transform'), getShaderSource('fs-transform'));

var programFeedback = createProgram(gl, getShaderSource('vs-feedback'), getShaderSource('fs-feedback'));
var programs = [programTransform, programFeedback];
Copy the code
  • Init Buffer
var VERTEX_COUNT = 6;
var positions = new Float32Array([-1.0, -1.0.0.0.1.0.1.0, -1.0.0.0.1.0.1.0.1.0.0.0.1.0.1.0.1.0.0.0.1.0,
    -1.0.1.0.0.0.1.0,
    -1.0, -1.0.0.0.1.0
]);

var BufferType = {
    VERTEX: 0.POSITION: 1.COLOR: 2.MAX: 3
};

var buffers = new Array(BufferType.MAX);
for (var i = 0; i < BufferType.MAX; ++i) {
    buffers[i] = gl.createBuffer();
}

// Transform buffer
gl.bindBuffer(gl.ARRAY_BUFFER, buffers[BufferType.VERTEX]);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);

// Feedback empty buffers
gl.bindBuffer(gl.ARRAY_BUFFER, buffers[BufferType.POSITION]);
gl.bufferData(gl.ARRAY_BUFFER, positions.length * Float32Array.BYTES_PER_ELEMENT, gl.STATIC_COPY);
gl.bindBuffer(gl.ARRAY_BUFFER, null);

gl.bindBuffer(gl.ARRAY_BUFFER, buffers[BufferType.COLOR]);
gl.bufferData(gl.ARRAY_BUFFER, positions.length * Float32Array.BYTES_PER_ELEMENT, gl.STATIC_COPY);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
Copy the code
  • Init Transform Vertex Array
var PROGRAM_TRANSFORM = 0;
var PROGRAM_FEEDBACK = 1;

// -- Init Transform Vertex Array
var vertexArrays = [gl.createVertexArray(), gl.createVertexArray()];
gl.bindVertexArray(vertexArrays[PROGRAM_TRANSFORM]);

var vertexPosLocation = 0; // set with GLSL layout qualifier
gl.bindBuffer(gl.ARRAY_BUFFER, buffers[BufferType.VERTEX]);
gl.vertexAttribPointer(vertexPosLocation, 4, gl.FLOAT, false.0.0);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.enableVertexAttribArray(vertexPosLocation);

gl.bindVertexArray(null);
Copy the code
  • Init TransformFeedback
// -- Init TransformFeedback
var transformFeedback = gl.createTransformFeedback();
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback);
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffers[BufferType.POSITION]);
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, buffers[BufferType.COLOR]);
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0.null);
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1.null);
Copy the code
  • Init Feedback Vertex Array
  • There is no bufferData
gl.bindVertexArray(vertexArrays[PROGRAM_FEEDBACK]);

var vertexPosLocationFeedback = 0; // set with GLSL layout qualifier
gl.bindBuffer(gl.ARRAY_BUFFER, buffers[BufferType.POSITION]);
gl.vertexAttribPointer(vertexPosLocationFeedback, 4, gl.FLOAT, false.0.0);
gl.enableVertexAttribArray(vertexPosLocationFeedback);

var vertexColorLocationFeedback = 3; // set with GLSL layout qualifier
gl.bindBuffer(gl.ARRAY_BUFFER, buffers[BufferType.COLOR]);
gl.vertexAttribPointer(vertexColorLocationFeedback, 4, gl.FLOAT, false.0.0);
gl.enableVertexAttribArray(vertexColorLocationFeedback);

gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.bindVertexArray(null);
Copy the code
  • render clear
gl.clearColor(0.0.0.0.0.0.1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
Copy the code
// First draw, capture the attributes
// Disable rasterization, vertices processing only
gl.enable(gl.RASTERIZER_DISCARD);

gl.useProgram(programs[PROGRAM_TRANSFORM]);
var matrix = new Float32Array([
    0.5.0.0.0.0.0.0.0.0.0.5.0.0.0.0.0.0.0.0.0.5.0.0.0.0.0.0.0.0.1.0
]);
gl.uniformMatrix4fv(mvpLocation, false, matrix);

gl.bindVertexArray(vertexArrays[PROGRAM_TRANSFORM]);
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback);

gl.beginTransformFeedback(gl.TRIANGLES);
gl.drawArraysInstanced(gl.TRIANGLES, 0, VERTEX_COUNT, 1);
gl.endTransformFeedback();
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);

gl.disable(gl.RASTERIZER_DISCARD);

// Second draw, reuse captured attributes
gl.useProgram(programs[PROGRAM_FEEDBACK]);
gl.bindVertexArray(vertexArrays[PROGRAM_FEEDBACK]);
gl.drawArraysInstanced(gl.TRIANGLES, 0, VERTEX_COUNT, 1);
gl.bindVertexArray(null);
Copy the code