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