【问题标题】:Strange errors during drawing hollow circles in the 3D space在 3D 空间中绘制空心圆时出现奇怪的错误
【发布时间】:2019-11-19 00:41:21
【问题描述】:

我正在尝试绘制两个空心圆,它们围绕着一个位于 0、0、0 位置的立方体..

到目前为止,我已经实现了立方体,这里的两个圆圈就是我得到的。

这里发生了两件奇怪的事情。

一个是我想画圆圈,但我可以看到从原点辐射出来的线。

第二个是插值颜色,即使我只为片段着色器设置了一种颜色。

你可以清楚地看到那些带有插值颜色的线条......

这是我的顶点着色器代码和片段着色器代码

"use strict";
const loc_aPosition = 1;
const loc_aColor = 2;
const loc_UVCoord = 3;
const VSHADER_SOURCE = 
`#version 300 es
layout(location=${loc_aPosition}) in vec4 aPosition;
layout(location=${loc_aColor}) in vec4 aColor;
layout(location=${loc_UVCoord}) in vec2 UVCoord;
out vec4 vColor;
out vec2 vUVCoord;
uniform mat4 uMVP;
void main()
{
    gl_Position = uMVP * aPosition;
    vColor = aColor;
    vUVCoord = UVCoord;
}`;

const FSHADER_SOURCE =
`#version 300 es
precision mediump float;
in vec4 vColor;
out vec4 fColor;
void main()
{
    fColor = vColor;
}`;

两个圆的初始化函数和唯一的区别是目标平面。

function init_equator(gl)
{
  let vertices = []; // for the vertices
  let color = [1, 0, 0]; // red color
  for(var i = 0; i <= 360; i+=10)
  {
    let j = i * Math.PI/180;
    let vert = [R * Math.cos(j), 0, R * Math.sin(j)]; // drawing a circle at the XZ plane since it has to be an equator for the cube...
    vertices.push( vert[0], vert[1], vert[2] );   // push the vertices
    vertices.push( color[0], color[1], color[2]); // set the color
  }  
  const SZ = vertices.BYTES_PER_ELEMENT;

  let vao = gl.createVertexArray();
  gl.bindVertexArray(vao);
  let vbo = gl.createBuffer();

  gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

  gl.vertexAttribPointer(loc_aPosition, 3, gl.FLOAT, false, SZ * 6, 0); // stride is 6, 3 for positions and 3 for the color
  gl.enableVertexAttribArray(loc_aPosition);


  gl.vertexAttribPointer(loc_aColor, 3, gl.FLOAT, false, SZ * 6, SZ * 3); // stride is 6, offset is this is because 3 color elements are located after 3 position elements..
  gl.enableVertexAttribArray(loc_aColor);

  gl.bindVertexArray(null);
  gl.bindBuffer(gl.ARRAY_BUFFER, null);

  return { vao, n : vertices.length / 3 }; // since it has three coordinates so devide by 3
}


function init_latitude(gl)
{
  let vertices = []; // for the vertices
  let color = [1, 0, 0]; // supposed to be the red
  for(var i = 0; i <= 360; i+=10)
  {
    let j = i * Math.PI/180;
    let vert = [0, R * Math.cos(j), R * Math.sin(j)]; // drawing a circle on the YZ plane
    vertices.push( vert[0], vert[1], vert[2] ); 
    vertices.push( color[0], color[1], color[2]);   
  }  
  const SZ = vertices.BYTES_PER_ELEMENT;

  let vao = gl.createVertexArray();
  gl.bindVertexArray(vao);
  let vbo = gl.createBuffer();

  gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

  gl.vertexAttribPointer(loc_aPosition, 3, gl.FLOAT, false, SZ * 6, 0); // stride is 6, 3 for positions and 3 for the color
  gl.enableVertexAttribArray(loc_aPosition);

  gl.vertexAttribPointer(loc_aColor, 3, gl.FLOAT, false, SZ * 6, SZ * 3); // stride is 6, offset is this is because 3 color elements are located after 3 position elements..
  gl.enableVertexAttribArray(loc_aColor);

  gl.bindVertexArray(null);
  gl.bindBuffer(gl.ARRAY_BUFFER, null);

  return { vao, n : vertices.length / 3 }; // since it has three coordinates so devide by 3
}

我从这里引用这些绘图功能drawing circle

在主函数中我这样调用draw函数..

........
MVP.setOrtho(LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR); // setting MVP matrix to orthographic mode
    MVP.lookAt(FIXED_X, FIXED_Y, FIXED_Z, 0,0,0, 0,1,0); // Eye position x, y, z Look at position 0, 0, 0 Up vector 0, 1, 0
    gl.uniformMatrix4fv(loc_MVP, false, MVP.elements);
    gl.bindVertexArray(cube.vao);
    gl.drawElements(gl.TRIANGLES, cube.n, gl.UNSIGNED_BYTE, 0)
    gl.bindVertexArray(null);
    gl.bindVertexArray(equator.vao);
    gl.drawArrays(gl.LINE_LOOP, 0, equator.n);
    gl.bindVertexArray(null);
    gl.bindVertexArray(latitudeCircle.vao);
    gl.drawArrays(gl.LINE_LOOP, 0, latitudeCircle.n);
    gl.bindVertexArray(null);

我不知道为什么线条会从原点和混合颜色散发出来......

有人可以帮帮我吗?

【问题讨论】:

    标签: webgl webgl2


    【解决方案1】:

    这一行,在您发布的代码中出现了两次

    const SZ = vertices.BYTES_PER_ELEMENT;
    

    SZ 将是undefinedvertices 是原生 JavaScript 数组,而不是像 Float32Array 这样的类型化数组。之后,SZ 的每个计算都将是 0NaN

    换句话说,这些行

      gl.vertexAttribPointer(loc_aPosition, 3, gl.FLOAT, false, SZ * 6, 0);
      gl.vertexAttribPointer(loc_aColor, 3, gl.FLOAT, false, SZ * 6, SZ * 3); 
    

      gl.vertexAttribPointer(loc_aPosition, 3, gl.FLOAT, false, 0, 0);
      gl.vertexAttribPointer(loc_aColor, 3, gl.FLOAT, false, 0, 0); 
    

    这意味着每隔一个位置都是一种颜色,而每隔一个颜色就是一个位置,它解释了为什么线条会到达中心以及为什么要插入颜色。

    请注意,如果您在调试器中单步调试过代码,您可能已经看到了这个问题,因此最好学习如何使用 the debugger

    另外仅供参考,与您的问题无关,您无需连续两次致电gl.bindVertexArray,一次与null 联系,一次与您要绘制的下一个事物联系。

    这个

        gl.bindVertexArray(cube.vao);
        gl.drawElements(gl.TRIANGLES, cube.n, gl.UNSIGNED_BYTE, 0)
        gl.bindVertexArray(null);
        gl.bindVertexArray(equator.vao);
        gl.drawArrays(gl.LINE_LOOP, 0, equator.n);
        gl.bindVertexArray(null);
        gl.bindVertexArray(latitudeCircle.vao);
        gl.drawArrays(gl.LINE_LOOP, 0, latitudeCircle.n);
        gl.bindVertexArray(null);
    

    只能这样

        gl.bindVertexArray(cube.vao);
        gl.drawElements(gl.TRIANGLES, cube.n, gl.UNSIGNED_BYTE, 0)
        gl.bindVertexArray(equator.vao);
        gl.drawArrays(gl.LINE_LOOP, 0, equator.n);
        gl.bindVertexArray(latitudeCircle.vao);
        gl.drawArrays(gl.LINE_LOOP, 0, latitudeCircle.n);
        gl.bindVertexArray(null);  // this is also not technically needed
    

    此外,您还可以使用展开运算符。

    这个

        vertices.push( vert[0], vert[1], vert[2] );   // push the vertices
        vertices.push( color[0], color[1], color[2]); // set the color
    

    可以这样

        vertices.push( ...vert );   // push the vertices
        vertices.push( ...color ); // set the color
    

    您也可能会发现these tutorials 很有用。

    【讨论】:

    • 非常感谢先生!我犯了非常愚蠢的错误...我无法想到 SZ 值是 0...我应该在调试期间更仔细地查看我的代码...祝您有美好的一天!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-26
    • 1970-01-01
    • 2017-04-01
    • 2022-10-30
    • 2013-03-31
    • 2016-07-27
    • 1970-01-01
    相关资源
    最近更新 更多