javascript - WebGL 重置顶点位置

标签 javascript random webgl

我正在创建一个简单的 webgl 程序,它将 3 个随机顶点放在 Canvas 上并将它们连接成一个三 Angular 形。我尝试添加平移以将三 Angular 形向右移动(增加每个顶点的 X 值),但当然如果它永远移动下去,三 Angular 形将超出 Canvas 。有谁知道如何检测顶点的 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>

最佳答案

为此,请考虑对您的代码进行以下更改:

  • 在顶点着色器中通过translation 移除顶点放置,让您“逐顶点”控制几何体的放置(translation 实际上意味着“对象级”放置,这不是你想要的)

  • 当您在loop() 中遍历 时,您会检查顶点坐标的模数。您应该像这样对迭代索引执行检查:if (points % 2 == 0)

  • 现在 translation 概念消失了,更新顶点坐标的位置,而不是模检查后的 translation 数组:indices[点] += 0.01;

  • 最后,看到您正在更新 indices 顶点数据,您需要更新 webgl buf 以确保您的更改在下一个时反射(reflect)出来渲染帧:

    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();
<canvas id="canvas"><canvas>

关于javascript - WebGL 重置顶点位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53930126/

相关文章:

Three.JS 的 JSON 格式

python - 为什么我在第二次运行中直接得到相同的结果而不在Python中运行随机函数?

c++ - 通过泊松过程生成随机到达 C++

c - 整数常量对于 "long"类型来说太大

javascript - Canvas 库处理 SVG 的方式和 SVG 库处理 SVG 的方式有什么区别?

javascript - 使用 Javascript 触发单选按钮

javascript - 超链接下载 img src 的任何内容

javascript - jquery,当字段失去焦点时提交表单

javascript - 单击按钮时如何滚动到顶部?

opengl-es - 带法线的盒多边形渲染显示奇怪的照明/颜色