WebGL重置顶点位置

时间:2018-12-26 09:36:27

标签: javascript random webgl

我正在创建一个简单的webgl程序,该程序将3个随机顶点放在画布上,并将它们连接成一个三角形。我尝试添加平移以将三角形向右移动(增加每个顶点的X值),但是当然,如​​果永远消失,三角形将从画布中消失。有谁知道如何检测顶点的x值是否大于1,如果是,请重置给定顶点的位置,因为我的解决方案似乎什么也没做,就像它甚至不会触发

var canvas = document.getElementById("canvas");
var gl = canvas.getContext("webgl");

gl.clearColor(0.1, 0.2, 0.2, 1.0);
gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);

var indices = [0, 0, 0, 0, 0, 0];
for (var points = 0; points < 6; points++) {
  indices[points] = (Math.random() * 2) - 1;
  //indices[points + 1] = Math.random() < 0.5 ? -1 : 1;
}

var buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(indices),
  gl.STATIC_DRAW);

var vert = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vert, `
      precision mediump float;

      attribute vec2 position;
      uniform vec2 translation;

      void main(){
        gl_Position = vec4(position + translation, 0.0, 1.0);
      }
      `);
gl.compileShader(vert);
var success1 = gl.getShaderParameter(vert, gl.COMPILE_STATUS);
if (!success1) {
  // Something went wrong during compilation; get the error
  throw gl.getShaderInfoLog(vert);
}

var frag = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(frag, `
      precision mediump float;
      void main(){
        gl_FragColor = vec4(0.3, 0.6, 0.4, 1.0);
      }
      `);
gl.compileShader(frag);
var success2 = gl.getShaderParameter(frag, gl.COMPILE_STATUS);
if (!success2) {
  // Something went wrong during compilation; get the error
  throw gl.getShaderInfoLog(frag);
}




var program = gl.createProgram();
gl.attachShader(program, vert);
gl.attachShader(program, frag);
gl.linkProgram(program);

var vertLoc = gl.getAttribLocation(program, "position");
gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, gl.FALSE, 0, 0);
gl.enableVertexAttribArray(vertLoc);

gl.useProgram(program);

var trans = gl.getUniformLocation(program, "translation");
var translation = [0.0, 0.0];
gl.uniform2fv(trans, translation);


gl.drawArrays(gl.TRIANGLES, 0, 3);

function loop() {
  gl.clearColor(0.1, 0.2, 0.2, 1.0);
  gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);
  translation[0] += 0.01;
  gl.uniform2fv(trans, translation);



  gl.drawArrays(gl.TRIANGLES, 0, 3);

  for (var points = 0; points < 6; points++) {
    if (indices[points] % 2 == 0) {
      if (indices[points] + translation[0] > 1) {
        indices[points] = (Math.random() * 2) - 1;
      }
    }
    //indices[points + 1] = Math.random() < 0.5 ? -1 : 1;
  }
  requestAnimationFrame(loop);
}
loop();
<canvas id="canvas"></canvas>

1 个答案:

答案 0 :(得分:0)

要实现此目的,请考虑对代码进行以下更改:

  • 在顶点着色器中通过x = np.array([1, 2, 3]) y = x z = np.copy(x) x[0] = 10 x[0] == y[0] True x[0] == z[0] False 删除顶点的位置,以使您可以“逐顶点”控制几何的位置(translation有效地表示“对象级”放置,不是您想要的东西)

  • 当您在translation中的points上进行迭代时,将检查顶点坐标的模。您应该像这样对迭代索引执行检查:loop()

  • 现在if (points % 2 == 0)概念已经消失了,在模检查后更新顶点坐标的位置,而不是translation数组:translation

  • 最后,看到您正在更新indices[points] += 0.01;顶点数据,就需要更新webgl indices,以确保您的更改在下一帧渲染时得到反映:

    buf

以下是完整的更新脚本:

gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(indices), gl.STATIC_DRAW);
var canvas = document.getElementById("canvas");
var gl = canvas.getContext("webgl");

gl.clearColor(0.1, 0.2, 0.2, 1.0);
gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);

var indices = [0, 0, 0, 0, 0, 0];
for (var points = 0; points < 6; points++) {
  indices[points] = (Math.random() * 2) - 1;
}

var buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(indices),
  gl.STATIC_DRAW);

var vert = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vert, `
          precision mediump float;

          attribute vec2 position;

          void main(){
            gl_Position = vec4(position, 0.0, 1.0);
          }
          `);
gl.compileShader(vert);
var success1 = gl.getShaderParameter(vert, gl.COMPILE_STATUS);
if (!success1) {
  throw gl.getShaderInfoLog(vert);
}

var frag = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(frag, `
          precision mediump float;
          void main(){
            gl_FragColor = vec4(0.3, 0.6, 0.4, 1.0);
          }
          `);
gl.compileShader(frag);
var success2 = gl.getShaderParameter(frag, gl.COMPILE_STATUS);
if (!success2) {
  throw gl.getShaderInfoLog(frag);
}

var program = gl.createProgram();
gl.attachShader(program, vert);
gl.attachShader(program, frag);
gl.linkProgram(program);

var vertLoc = gl.getAttribLocation(program, "position");
gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, gl.FALSE, 0, 0);
gl.enableVertexAttribArray(vertLoc);

gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 3);

function loop() {
  gl.clearColor(0.1, 0.2, 0.2, 1.0);
  gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);

  gl.drawArrays(gl.TRIANGLES, 0, 3);

  // Update the vertex data, causing the vertex x coordinate to increase per-frame
  for (var points = 0; points < 6; points++) {

    // Only process x coordinate
    if (points % 2 == 0) {

      // Increase x coordinate per-frame
      indices[points] += 0.01;

      // If x position > 1 reset it to a new random value
      if (indices[points] > 1) {
        indices[points] = (Math.random() * 2) - 1;
      }
    }
  }

  // Update webgl vertex buffer so that updated indices data is rendered
  gl.bindBuffer(gl.ARRAY_BUFFER, buf);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(indices), gl.STATIC_DRAW);

  requestAnimationFrame(loop);
}
loop();