圆圈没有渲染到画布上

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

我正试图使用WebGL渲染一个圆。我只需要通过一个动态像素值来转换圆,因此我使用了教程中的一些转换逻辑,将像素空间转换为剪贴空间,并将其放在顶点着色器中。我还使用了常见的 TRIANGLE_FAN 的技术来制作圆形。

我目前在画布上看不到任何东西,它渲染成一个白色的屏幕,任何地方都没有圆。我只想让圆的半径为1px。

//shaders
const glsl = (x) => x;

const vertex = glsl`
  attribute vec2 a_position;

  uniform vec2 u_resolution;
  uniform vec2 u_translation;

  void main() {

    //add in the translation
    vec2 position = a_position + u_translation;

    // convert the circle points from pixels to 0.0 to 1.0
    vec2 zeroToOne = a_position / u_resolution;

    // convert from 0->1 to 0->2
    vec2 zeroToTwo = zeroToOne * 2.0;

    // convert from 0->2 to -1->+1 (clipspace)
    vec2 clipSpace = zeroToTwo - 1.0;

    gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
  }
`;

const fragment = glsl`
  precision mediump float;

  uniform vec4 u_color;

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

function main() {
  // Get A WebGL context
  var canvas = document.querySelector("#c");
  var gl = canvas.getContext("webgl");
  if (!gl) {
    return;
  }

  const opacity = 0.5; //opacity will be dynamic
  const color = [0, 0, 0, opacity];
  const translation = [50, 50]; //this translation value with be dynamic but using [50,50] for demo purposes

  // Use our boilerplate utils to compile the shaders and link into a program
  var program = webglUtils.createProgramFromScripts(gl, [vertex, fragment]);

  // look up where the vertex data needs to go.
  var positionAttributeLocation = gl.getAttribLocation(program, "a_position");

  // look up uniform locations
  var resolutionUniformLocation = gl.getUniformLocation(program,"u_resolution");
  var translationUniformLocation = gl.getUniformLocation(program, "u_translation");
  var colorUniformLocation = gl.getUniformLocation(program, "u_color");

  // Create a buffer to put three 2d clip space points in
  var positionBuffer = gl.createBuffer();

  // Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

  const positions = [
    0.0, 0.0 //circle center vertex
  ];

  const stops = 100;

  for (i = 0; i < stops; i++){
    positions.push(Math.cos(i * 2 * Math.PI/stops)); // x coord
    positions.push(Math.sin(i * 2 * Math.PI/stops)); // y coord
  }

  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

  //sets canvas width and height to current size of canvas as specified in css
  webglUtils.resizeCanvasToDisplaySize(gl.canvas);

  // Tell WebGL how to convert from clip space to pixels
  gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

  // Clear the canvas
  gl.clearColor(0, 0, 0, 0);
  gl.clear(gl.COLOR_BUFFER_BIT);

  // Tell it to use our program (pair of shaders)
  gl.useProgram(program);

  // Turn on the attribute
  gl.enableVertexAttribArray(positionAttributeLocation);

  // Bind the position buffer.
  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

  // Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER)
  var size = 2; // 2 components per stop
  var type = gl.FLOAT; // the data is 32bit floats
  var normalize = false; // don't normalize the data
  var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
  var offset = 0; // start at the beginning of the buffer
  gl.vertexAttribPointer(
    positionAttributeLocation,
    size,
    type,
    normalize,
    stride,
    offset
  );

  // set the resolution
  gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);

  //set the translation
  gl.uniform2fv(translationUniformLocation, translation);

  //set the color
  gl.uniform4fv(colorUniformLocation, color);


  // draw
  var primitiveType = gl.TRIANGLE_FAN;
  var offset = 0;
  const count = stops + 1; //adding one for center of circle
  gl.drawArrays(primitiveType, offset, count);
}

main();
<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
<canvas id="c"></canvas>
webgl
1个回答
1
投票

上面的代码有3个问题

  1. 它在呼唤 createProgramFromScripts 而不是 createProgramFromSources

  2. 该着色器没有使用 u_translation

    这是前两行

    //add in the translation
    vec2 position = a_position + u_translation;
    
    // convert the circle points from pixels to 0.0 to 1.0
    vec2 zeroToOne = a_position / u_resolution;
    

    第二行是使用 a_position 而不是 position

  3. 扇子少了最后一个三角形。

    你可能要 <= stops 在你的for循环中

我强烈建议你按照教程去做。那里 并习惯使用矩阵。他们从像上面的代码那样的着色器代码开始,但逐渐发展到用矩阵来代替它。即使对于像素来说,矩阵也能实现许多没有矩阵就很难实现的东西。

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