这真的没什么大不了的,一旦你了解了如何使用顶点缓冲区和着色器。然后你可以很容易地编写一个实用函数来完成它。如果您正在寻找参考,这是我通常使用的一个:
drawFullScreenQuad : function(shaderProgram) {
if (!shaderProgram)
{
utils.warning("Missing the shader program!");
return;
}
// Only created once
if (this.screenQuadVBO == null)
{
var verts = [
// First triangle:
1.0, 1.0,
-1.0, 1.0,
-1.0, -1.0,
// Second triangle:
-1.0, -1.0,
1.0, -1.0,
1.0, 1.0
];
this.screenQuadVBO = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.screenQuadVBO);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(verts), this.gl.STATIC_DRAW);
}
// Bind:
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.screenQuadVBO);
this.gl.enableVertexAttribArray(shaderProgram.vertexAttributes.vertexPositionNDC);
this.gl.vertexAttribPointer(shaderProgram.vertexAttributes.vertexPositionNDC, 2, this.gl.FLOAT, false, 0, 0);
// Draw 6 vertexes => 2 triangles:
this.gl.drawArrays(this.gl.TRIANGLES, 0, 6);
// Cleanup:
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
},
然后你可以像我一样在顶点着色器中即时计算纹理坐标:
顶点着色器:
precision lowp float;
// xy = vertex position in normalized device coordinates ([-1,+1] range).
attribute vec2 vertexPositionNDC;
varying vec2 vTexCoords;
const vec2 scale = vec2(0.5, 0.5);
void main()
{
vTexCoords = vertexPositionNDC * scale + scale; // scale vertex attribute to [0,1] range
gl_Position = vec4(vertexPositionNDC, 0.0, 1.0);
}
片段着色器:
precision mediump float;
uniform sampler2D colorMap;
varying vec2 vTexCoords;
void main()
{
gl_FragColor = texture2D(colorMap, vTexCoords);
}
需要注意的重点是归一化设备坐标 (NDC) 中的顶点,因此您只需将 [-1,1] 范围内的顶点传递并直接将它们转发到gl_Position,而无需乘以投影矩阵。