Skip to content Skip to sidebar Skip to footer

Why Is The Webgl Instancing Extension Only Drawing One Triangle Instead Of Two?

I'm trying to use instancing with WebGL based on this guide. I've tried to create a simple example that draws a red triangle on the left and a blue triangle on the right. When I ru

Solution 1:

So I see you mostly already got an answer in the comments.

The code is drawing the first triangle twice, once in red, then once in blue.

But, ... you mentioned indexing a uniform array. That would be unusual

Normally you'd put per instance data in a buffer. The example on the site linked used a matrix just to be generic since a matrix well will let you do just about any math (translation, rotation, scale, 3d projection, ...) but just as an example, you could just pass in single x offset.

const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl");
const ext = gl.getExtension("ANGLE_instanced_arrays");
const vert = gl.createShader(gl.VERTEX_SHADER);
const frag = gl.createShader(gl.FRAGMENT_SHADER);
const program = gl.createProgram();

gl.shaderSource(vert, `
  attribute vec4 a_position;
  attribute float a_xoffset;
  attribute vec4 a_color;
  varying vec4 v_color;

  void main() {
    gl_Position = a_position;
    gl_Position.x += a_xoffset;
    v_color = a_color;
  }
`);

gl.shaderSource(frag, `
  precision mediump float;
  varying vec4 v_color;

  void main() {
    gl_FragColor = v_color;
  }
`);

gl.compileShader(vert);
gl.compileShader(frag);
gl.attachShader(program, vert);
gl.attachShader(program, frag);
gl.linkProgram(program);

const a_position = gl.getAttribLocation(program, "a_position");
const buffer1 = gl.createBuffer();
const positions = [-0.5, 0, -0.5, 0.2, -0.3, 0];
gl.bindBuffer(gl.ARRAY_BUFFER, buffer1);
gl.bufferData(gl.ARRAY_BUFFER, newFloat32Array(positions), gl.STATIC_DRAW);

const a_color = gl.getAttribLocation(program, "a_color");
const buffer2 = gl.createBuffer();
const colors = [1, 0, 0, 1, 0, 0, 1, 1];
gl.bindBuffer(gl.ARRAY_BUFFER, buffer2);
gl.bufferData(gl.ARRAY_BUFFER, newFloat32Array(colors), gl.STATIC_DRAW);

const a_xoffset = gl.getAttribLocation(program, "a_xoffset");
const buffer3 = gl.createBuffer();
const xoffsets = [0, 1];
gl.bindBuffer(gl.ARRAY_BUFFER, buffer3);
gl.bufferData(gl.ARRAY_BUFFER, newFloat32Array(xoffsets), gl.STATIC_DRAW);

gl.viewport(0, 0, 300, 300);
gl.useProgram(program);

gl.bindBuffer(gl.ARRAY_BUFFER, buffer1);
gl.enableVertexAttribArray(a_position);
gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, 0, 0);

gl.bindBuffer(gl.ARRAY_BUFFER, buffer2);
gl.enableVertexAttribArray(a_color);
gl.vertexAttribPointer(a_color, 4, gl.FLOAT, false, 0, 0);
ext.vertexAttribDivisorANGLE(a_color, 1);

gl.bindBuffer(gl.ARRAY_BUFFER, buffer3);
gl.enableVertexAttribArray(a_xoffset);
gl.vertexAttribPointer(a_xoffset, 1, gl.FLOAT, false, 0, 0);
ext.vertexAttribDivisorANGLE(a_xoffset, 1);

ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 3, 2);
<canvasid="canvas"width="300"height="300"></canvas>

I'm just pointing that out because you have millions of values in a buffer but uniforms are far more limited so indexing a uniform for instancing is not common.

If you actually wanted different data per instance then yes you'd have to do something else.

One example is here

Post a Comment for "Why Is The Webgl Instancing Extension Only Drawing One Triangle Instead Of Two?"