我正在使用 WebGL2 并尝试调用 gl.drawArraysInstanced 来绘制多个形状。gl.drawArraysInstanced 的第一次调用可以绘制 2 个或更多元素。
gl.drawArraysInstanced(gl.TRIANGLES, 0, numVertices, 3);
然后我在 3 秒后调用相同的函数,但它只绘制一个三角形。(见下面的例子)
var canvas = document.getElementById('canvas');
gl = canvas.getContext('webgl2');
var cube = {};
var vertices = [
-0.2, -0.2, 0,
0.2, -0.2, 0,
0.2, 0.2, 0,
];
var numVertices = vertices.length / 3;
var vertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
var vertexShader = getAndCompileShader('vertexShader', 'vertex');
var fragmentShader = getAndCompileShader('fragmentShader', 'fragment');
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
var vao = gl.createVertexArray();
gl.bindVertexArray(vao);
var positionAttributeLocation = gl.getAttribLocation(shaderProgram, 'position');
gl.enableVertexAttribArray(positionAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
function getAndCompileShader(id, shaderType) {
var shader;
var shaderElement = document.getElementById(id);
var shaderText = shaderElement.text.trim();
shader = gl.createShader(
shaderType==='vertex' ? gl.VERTEX_SHADER : gl.FRAGMENT_SHADER
);
gl.shaderSource(shader, shaderText);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.log(gl.getShaderInfoLog(shader));
return true;
}
console.log('Shader ' + id + ' compiled.')
return shader;
}
function start() {
gl.clearColor(.5,0,0,1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bindVertexArray(vao);
gl.drawArraysInstanced(gl.TRIANGLES, 0, numVertices, 2);
console.log('Drawing 2 triangles');
setTimeout(function() {
gl.clearColor(.5,0,0,1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArraysInstanced(gl.TRIANGLES, 0, numVertices, 2);
console.log('Drawing 2 triangles again');
}, 3000);
}
start();
<script id="vertexShader" type="x-shader/x-vertex">
#version 300 es
in vec3 position;
void main() {
if(gl_InstanceID==0) {
gl_Position = vec4(position.x - 0.2, position.yz, 1);
} else {
gl_Position = vec4(position.x + 0.2, position.yz, 1);
}
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
#version 300 es
precision mediump float;
out vec4 finalColor;
void main() {
finalColor = vec4(0.5,0.5,0.5,1.0);;
}
</script>
<body>
<canvas id="canvas" style="width: 300px; height: 200px" width="600" height="400"></canvas>
</body>
另外,调用gl.drawArraysInstanced 是否应该比gl.drawArrays更有效?谢谢