代码之家  ›  专栏  ›  技术社区  ›  Danny Raufeisen

WebGL不喜欢带索引绘图的Index 255

  •  1
  • Danny Raufeisen  · 技术社区  · 2 年前

    这里是一个最小的WebGL测试程序,它创建了一个单一uint8值为255的索引缓冲区。它应该画一个64px大小的红色正方形,但它没有(索引值对绘制来说并不重要)。

    WebGL会忽略索引为255的元素,尽管它属于无符号字节范围。使用254或其他值,红色方块将按预期显示。

    这是WebGL的错误还是预期行为?我什么也找不到。

    <canvas width="800" height="600"></canvas>
    <script>
    let canvas = document.querySelector("canvas");
    let gl = canvas.getContext("webgl2");
    let vert = gl.createShader(gl.VERTEX_SHADER);
    let frag = gl.createShader(gl.FRAGMENT_SHADER);
    let prog = gl.createProgram();
    let index_buf = gl.createBuffer();
    
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buf);
    
    gl.bufferData(
        gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([255]), gl.STATIC_DRAW
    );
    
    gl.shaderSource(vert, `#version 300 es
        void main()
        {
            gl_Position = vec4(0,0,0,1);
            gl_PointSize = 64.0;
        }
    `);
    
    gl.shaderSource(frag, `#version 300 es
        precision highp float;
        out vec4 color;
        void main()
        {
            color = vec4(1,0,0,1);
        }
    `);
    
    gl.compileShader(vert);
    gl.compileShader(frag);
    gl.attachShader(prog, vert);
    gl.attachShader(prog, frag);
    gl.linkProgram(prog);
    gl.clearColor(0, 0, 0, 1);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.useProgram(prog);
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buf);
    gl.drawElements(gl.POINTS, 1, gl.UNSIGNED_BYTE, 0);
    </script>
    
    1 回复  |  直到 2 年前
        1
  •  5
  •   Rabbid76    2 年前

    看见 WebGL 2.0 Specification - PRIMITIVE_RESTART_FIXED_INDEX is always enabled :

    在OpenGL ES 3.0中使用“启用/禁用”控制的PRIITIVE_RESTART_FIXED_INDEX上下文状态在WebGL 2.0中不受支持 相反,WebGL 2.0的行为就好像此状态一直处于启用状态一样。与WebGL 1.0相比,这是一个兼容性差异。

    drawElements、drawElementsInstrated或drawRangeElements处理索引时,如果索引的值是数据类型的最大值( 255表示UNSIGNED_BYTE索引 ,65535表示UNSIGNED_SHORT,或4294967295表示UNSIGNED_INT)。。。

    因此,如果索引类型为 UNSIGNED_BYTE ,索引255是 primitive restart 索引,不能用于索引顶点。