为什么WebGL实例化扩展仅绘制一个三角形而不是两个三角形?

问题描述 投票:0回答:1

我正在尝试基于this guide的WebGL使用实例化。我尝试创建一个简单的示例,在左侧绘制一个红色三角形,在右侧绘制一个蓝色三角形。运行它时,它在左侧绘制了一个蓝色三角形,我不明白为什么。

我尝试将参数更改为drawArraysInstancedANGLE,但这无济于事。我尝试更改绑定缓冲区的行顺序和设置属性指针等。我在做什么错呢?谢谢

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 vec4 a_color;
  varying vec4 v_color;

  void main() {
    gl_Position = a_position;
    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, 0.5, 0, 0.5, 0.2, 0.3, 0];
gl.bindBuffer(gl.ARRAY_BUFFER, buffer1);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(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, new Float32Array(colors), 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);

ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 3, 2);
<canvas id="canvas" width="300" height="300"></canvas>
javascript webgl
1个回答
1
投票

所以我看到您的评论中大多数人已经得到了答案。

该代码绘制了第一个三角形两次,一次绘制为红色,然后一次绘制为蓝色。

但是,...您提到了索引统一数组。那是不寻常的

通常,您会将每个实例的数据放入缓冲区。链接的站点上的示例仅使用了通用矩阵,因为矩阵可以让您进行几乎所有的数学运算(平移,旋转,缩放,3d投影等),但作为示例,您可以传入单x偏移。

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, new Float32Array(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, new Float32Array(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, new Float32Array(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);
<canvas id="canvas" width="300" height="300"></canvas>

我只是指出这一点,因为您在缓冲区中有数百万个值,但是统一性受到的限制要大得多,因此索引用于实例化的统一性并不常见。

如果您实际上每个实例需要不同的数据,那么您必须做其他事情。

一个例子是here

© www.soinside.com 2019 - 2024. All rights reserved.