WebGL警告:"属性0被禁用。这有很大的性能损失"

时间:2013-11-30 20:23:56

标签: javascript html5 canvas webgl

当我运行下面的JavaScript / WebGL代码(请向下滚动)时,我在开发控制台中看到以下警告消息:

[.WebGLRenderingContext]
PERFORMANCE WARNING: Attribute 0 is disabled.
This has significant performance penalty

下面的代码在画布上成功绘制了一个白点。但是,我希望警告消失。我需要在下面的代码中更改以使其停止显示?

HTML:

<!DOCTYPE html>
<html>
<body>
  <canvas id="canvas" width="100" height="100"></canvas>
</body>
</html>

JavaScript:

var
    VERTEX_SHADER_SOURCE = ""+
      "void main() {"+
      "  gl_Position = vec4(0.0, 0.0, 0.0, 1.0);"+
      "  gl_PointSize = 10.0;"+
      "}",

    FRAGMENT_SHADER_SOURCE = ""+
      "void main() {"+
      "  gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);"+
      "}",

    canvas = document.getElementById('canvas'),
    gl = canvas.getContext('webgl'),

    vertexShader = gl.createShader(gl.VERTEX_SHADER),
    fragmentShader = gl.createShader(gl.FRAGMENT_SHADER),

    shaderProgram = gl.createProgram();

// Compile the shaders.
gl.shaderSource(vertexShader, VERTEX_SHADER_SOURCE);
gl.compileShader(vertexShader);
gl.shaderSource(fragmentShader, FRAGMENT_SHADER_SOURCE);
gl.compileShader(fragmentShader);

// Create linked program.
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);    

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

// Draw the point.
gl.drawArrays(gl.POINTS, 0, 1);

这是一个极小但完整的例子,所以我正在寻找一个答案,告诉我具体要改变什么。 Here is a JSFiddle of the case。我在Chrome 30.0.1599.101(在OS X 10.8.5上)运行它。

4 个答案:

答案 0 :(得分:11)

OpenGL要求启用属性零,否则它将不会呈现任何内容。另一方面,WebGL所基于的OpenGL ES 2.0却没有。因此,要在OpenGL上模拟OpenGL ES 2.0,如果不启用属性0,浏览器必须为您创建一个足够大的缓冲区,以便为您请求绘制的顶点数量填充,并使用正确的值填充它(请参阅gl.vertexAttrib),将其附加到属性零,然后启用它。

它在幕后完成所有这些工作,但重要的是要知道创建和填充缓冲区需要时间。浏览器可以进行优化,但在一般情况下,如果你假设你在OpenGL ES 2.0上运行并使用属性零作为常量,就像你本应该能做的那样,没有警告就没有了浏览器代表您做的工作的想法,以模拟OpenGL ES 2.0与OpenGL不同的功能。

在您的特定情况下,警告没有多大意义。看起来你只是画了一个点。但是浏览器想出这一点并不容易,所以只要你画画并且没有启用属性0就会警告你。

答案 1 :(得分:9)

我设法让警告消失,在这里使用其他回复中的线索。我将回答我自己的问题,因为我已经得到了上面提供的案例的具体解决方案。

以下是我所做的改变(一般来说)以使警告静音:

  1. 在顶点着色器中为位置创建属性变量。
  2. 创建一个缓冲区对象,将其绑定到数组缓冲区,并将顶点数据写入其中。
  3. 将属性变量绑定到位置0
  4. 将缓冲区对象分配给属性变量。
  5. 启用属性变量的分配。
  6. 以下是a diff of the specific changes,此处为a JSFiddle demonstrating the code working without the warning


    为了防止这些链接在将来某个时候死亡,我在这里提供相关的代码片段:

    顶点着色器源应更改为:

    attribute vec4 a_Position;
    void main() {
      gl_Position = a_Position;
      gl_PointSize = 10.0;
    }
    

    以下JavaScript代码应插在gl.useProgram(shaderProgram)行的正下方:

    var vertices = new Float32Array([0.0, 0.0, 0.0]),
        vertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
    gl.bindAttribLocation(shaderProgram, 0, 'a_Position');
    gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(0);
    

答案 2 :(得分:0)

这个问题与你的问题类似:

Getting 'PERFORMANCE WARNING' messages in Chrome

也许它会有所帮助。

答案 3 :(得分:0)

我最近遇到了同样的问题并通过明确绑定属性0解决了这个问题,但是我认为你的解决方案不应该起作用。

取自gl.bindAttribLocation手册页:

  

a的属性变量name-to-generic属性索引绑定   程序对象可以随时通过调用显式分配   glBindAttribLocation。属性绑定直到生效才会生效   glLinkProgram被调用。程序对象链接后   成功地,通用属性的索引值保持固定   (并且可以查询它们的值),直到发生下一个链接命令。

详细说明绑定在链接着色器程序之后才会生效。

指出

也许有用
  

未明确绑定的活动属性将受到绑定   调用glLinkProgram时的链接器。

根据经验,他们似乎没有特定的顺序绑定,所以这通常是为什么属性0可以取消启用(在我的情况下,假设顶点着色器中的第一个用户定义属性将绑定到属性0 )。