WebGL Сброс позиций вершин - PullRequest
0 голосов
/ 26 декабря 2018

Я создаю простую программу 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 голосов
/ 27 декабря 2018

Чтобы добиться этого, рассмотрите возможность внесения следующих изменений в свой код:

  • уберите размещение вершин на translation в своем вершинном шейдере, чтобы дать вам контроль над каждой вершинойразмещение геометрии (translation эффективно означает размещение «на уровне объекта», что здесь не то, что вам нужно)

  • , когда вы перебираете points в loop(), вы проверяете по модулю координаты вершины.Вы должны выполнить эту проверку индекса итерации следующим образом: if (points % 2 == 0)

  • теперь, когда концепция translation исчезла, обновите положение координаты вершины, а не translation массив после проверки по модулю: indices[points] += 0.01;

  • наконец, когда вы обновляете данные вершин indices, вам нужно обновить webgl 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();
<canvas id="canvas"><canvas>
...