WebGL中的纹理映射问题及纹理映射位置的确定

WebGL中的纹理映射问题及纹理映射位置的确定,webgl,webgl2,Webgl,Webgl2,我试图在立方体上映射纹理,但我遇到了两个问题和一个问题 下面是初始化多维数据集的代码 function init_cube(gl, n) { const vertices = new Float32Array([ // Vertex coordinates 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0,-1.0, 1.0, 1.0,-1.0, 1.0, // v0-v1-v2-v3 front, Pass

我试图在立方体上映射纹理,但我遇到了两个问题和一个问题

下面是初始化多维数据集的代码

function init_cube(gl, n)
  {
      const vertices = new Float32Array([   // Vertex coordinates
        1.0, 1.0, 1.0,  -1.0, 1.0, 1.0,  -1.0,-1.0, 1.0,   1.0,-1.0, 1.0,  
        // v0-v1-v2-v3 front, Pass
        1.0, 1.0, 1.0,   1.0,-1.0, 1.0,   1.0,-1.0,-1.0,   1.0, 1.0,-1.0,  
        // v0-v3-v4-v5 right, No
        1.0, 1.0, 1.0,   1.0, 1.0,-1.0,  -1.0, 1.0,-1.0,  -1.0, 1.0, 1.0,  
        // v0-v5-v6-v1 up, Pass
       -1.0, 1.0, 1.0,  -1.0, 1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0,-1.0, 1.0,  
       // v1-v6-v7-v2 left, Pass
       -1.0,-1.0,-1.0,   1.0,-1.0,-1.0,   1.0,-1.0, 1.0,  -1.0,-1.0, 1.0,  
       // v7-v4-v3-v2 down, No
        1.0,-1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0, 1.0,-1.0,   1.0, 1.0,-1.0
      // v4-v7-v6-v5 back, Pass
     ]);

    const indices = new Uint8Array([       // Indices of the vertices
      0, 1, 2,   0, 2, 3,    // front
      4, 5, 6,   4, 6, 7,    // right
      8, 9,10,   8,10,11,    // up
     12,13,14,  12,14,15,    // left
     16,17,18,  16,18,19,    // down
     20,21,22,  20,22,23     // back
   ]);


    const vao = gl.createVertexArray();
    gl.bindVertexArray(vao);
    const indexBuffer = gl.createBuffer();

    if(!indexBuffer)
    {
      console.log("Failed to create an index buffer");
      return;
    }

    if(!initArrayBuffer(gl, vertices, 3, gl.FLOAT, loc_aPosition))
    {
      console.log("Failed to initialize an array buffer for the position");
      return;
    }


    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);


    init_texture(gl);

    gl.bindVertexArray(null);

    return {vao, n:indices.length};
}
纹理的代码,我在编写代码时引用了这个

function init_texture(gl)
{  
    const UVCoord = new Float32Array
    (
      [
        //First Pass
        0, 0.75,
        0.25, 0.75,
        0.25, 0.5,
        0, 0.5,
        0, 0.75,
        0.25, 0.5,
        //Second Pass
        0.25, 0.75,
        0.5, 0.5,
        0.5, 0.75,
        0.25, 0.75,
        0.25, 0.5,
        0.5, 0.5,
        //Third Pass
        0.5, 0.75,
        0.75, 0.75,
        0.75, 0.5,
        0.5, 0.5,
        0.5, 0.75,
        0.75, 0.5,
        //Fourth Pass
        1, 0.5,
        0.75, 0.75,
        1, 0.75,
        1, 0.5,
        0.75, 0.5,
        0.75, 0.75,
        //Sixth No
        0.75, 0.25,
        0.5, 0.5,
        0.5, 0.25,
        0.75, 0.25,
        0.75, 0.5,
        0.5, 0.5,
        //Fifth No 
        0.75, 0.75,
        0.5, 1,
        0.5, 0.75,
        0.75, 0.75,
        0.75, 1,
        0.5, 1
      ]
    );

    let UVCoordBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, UVCoordBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, UVCoord, gl.STATIC_DRAW);


    gl.vertexAttribPointer(loc_UVCoord, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(loc_UVCoord);

    let texture = gl.createTexture();
    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
      new Uint8Array([0, 0, 255, 255]));
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);


    let image = new Image();
    let url = "https://live.staticflickr.com/65535/49093406911_7d185dba0e_b.jpg";
    requestCORSIfNotSameOrigin(image, url);
    image.src = url;
    image.onload = function() 
    {
      loadTexture(gl, texture, image);
    }
}

function loadTexture(gl, texture, image)
{
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
  gl.generateMipmap(gl.TEXTURE_2D);
}

....

function requestCORSIfNotSameOrigin(img, url) //https://webgl2fundamentals.org/webgl/lessons/webgl-cors-permission.html
{
  if ((new URL(url)).origin !== window.location.origin) 
  {
    img.crossOrigin = "";
  }
}

....
第一个问题是纹理没有在主功能中加载这是因为
loadTexure
功能在主功能完成后开始,因此,是否仍有方法在第一次绘制立方体时加载纹理

这些是解决上述问题的图片

按箭头键更改角度后

第二个问题是纹理未正确应用于立方体右侧和底部

通过更改纹理坐标,我可以看到立方体上的1、2、3、4,但无论我如何编辑坐标顺序,我仍然无法看到立方体右侧和底部的5、6。。。这是纹理

最后一个问题是,如果我想改变要映射的面,我必须修改纹理坐标数组、索引数组或顶点数组吗

第一个问题是纹理没有在主函数中加载这是因为LoadTezure函数在主函数完成后开始,所以,是否仍有在第一次绘制立方体时加载纹理的方法

纹理是异步加载的,因此您有大约3种选择

  • 等待纹理加载后再开始

  • 创建可渲染纹理,使用requestAnimationFrame循环连续渲染,在加载图像时将纹理内容替换为图像

    因为你的渲染循环可以解决渲染问题

  • 创建可渲染纹理,在加载图像后将纹理内容替换为图像,然后再次渲染

  • 看起来您当前正在执行#3,但在加载纹理后不会再次渲染。在
    loadTexture
    函数中调用渲染/绘制函数

    如果要执行#1,需要创建
    图像
    ,并将其
    onload
    设置在代码其余部分之外。差不多

    const img = new Image();
    img.onload = initRestOfCode;
    img.src = urlForImage;
    
    function initRestOfCode() { ...
    
    第二个问题是纹理未正确应用于立方体右侧和底部

    只需首先检查,就可以启用深度测试和面剔除

    gl.enable(gl.DEPTH_TEST);
    gl.enable(gl.CULL_FACE);
    
    但除此之外,纹理坐标与顶点位置不匹配。每个立方体面有4个顶点位置,但代码每个立方体面有6个纹理坐标。它们需要匹配,每个面只有4个纹理坐标。WebGL中的属性表示并行数组


    第一个问题很简单。。。我觉得自己很笨,一个人也找不到。。第二个是,我不知道我只需要四个纹理坐标来映射立方体,我一直认为纹理坐标需要6个点,但这是我的偏见。。。非常感谢你,先生!祝您愉快,先生!在正常情况下,属性必须具有相同数量的值。他们代表