最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - WebGL warning: "Attribute 0 is disabled. This has significant performance penalty" - Stack Overfl

programmeradmin2浏览0评论

When I run the JavaScript/WebGL code below (please scroll down), I see the following warning message in my development console:

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

The code below successfully draws a white dot on the canvas. However, I want the warning to go away. What do I need to change in the code below to make it stop appearing?

The HTML:

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

The 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);
glpileShader(vertexShader);
gl.shaderSource(fragmentShader, FRAGMENT_SHADER_SOURCE);
glpileShader(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);

This is a minimal, but complete example, so I'm looking for an answer that tells me specifically what to change. Here is a JSFiddle of the case. I'm running this in Chrome 30.0.1599.101 (on OS X 10.8.5).

When I run the JavaScript/WebGL code below (please scroll down), I see the following warning message in my development console:

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

The code below successfully draws a white dot on the canvas. However, I want the warning to go away. What do I need to change in the code below to make it stop appearing?

The HTML:

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

The 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);

This is a minimal, but complete example, so I'm looking for an answer that tells me specifically what to change. Here is a JSFiddle of the case. I'm running this in Chrome 30.0.1599.101 (on OS X 10.8.5).

Share Improve this question edited Nov 30, 2013 at 22:40 GladstoneKeep asked Nov 30, 2013 at 20:23 GladstoneKeepGladstoneKeep 3,9723 gold badges30 silver badges39 bronze badges 1
  • 1 Well to do anything useful with webgl, you'll eventually want to get attribute locations and use them (to send vertices, colors, etc.) The warning might go away then. – pixelmike Commented Dec 1, 2013 at 0:24
Add a comment  | 

4 Answers 4

Reset to default 12

OpenGL requires attribute zero to be enabled otherwise it will not render anything. On the other hand OpenGL ES 2.0 on which WebGL is based does not. So, to emulate OpenGL ES 2.0 on top of OpenGL if you don't enable attribute 0 the browser has to make a buffer for you large enough for the number of vertices you've requested to be drawn, fill it with the correct value (see gl.vertexAttrib), attach it to attribute zero, and enable it.

It does all this behind the scenes but it's important for you to know that it takes time to create and fill that buffer. There are optimizations the browser can make but in the general case, if you were to assume you were running on OpenGL ES 2.0 and used attribute zero as a constant like you are supposed to be able to do, without the warning you'd have no idea of the work the browser is doing on your behalf to emulate that feature of OpenGL ES 2.0 that is different from OpenGL.

In your particular case the warning doesn't have much meaning. It looks like you are only drawing a single point. But it would not be easy for the browser to figure that out so it just warns you anytime you draw and attribute 0 is not enabled.

I've managed to get the warning to disappear, using clues in the other responses here. I'm going to answer my own question since I've got the specific solution for the case I provided above.

Here are changes I made (generically speaking) to silence the warning:

  1. Create an attribute variable in the vertex shader for the position.
  2. Create a buffer object, bind it to the array buffer, and write the vertex data to it.
  3. Bind the attribute variable to location 0.
  4. Assign the buffer object to the attribute variable.
  5. Enable assignment to the attribute variable.

Here is a diff of the specific changes, and here is a JSFiddle demonstrating the code working without the warning.


Just in case those links die at some point in the future, I'm providing the relevant code snippets here:

The vertex shader source should be changed to:

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

And the following JavaScript code should be inserted immediately below the gl.useProgram(shaderProgram) line:

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);

This question is similar to yours:

Getting 'PERFORMANCE WARNING' messages in Chrome

Maybe it will help.

I recently had the same problem and solved it by explicitly binding attribute 0, however I'm under the impression that your solution shouldn't work.

Taken from the gl.bindAttribLocation man page:

Attribute variable name-to-generic attribute index bindings for a program object can be explicitly assigned at any time by calling glBindAttribLocation. Attribute bindings do not go into effect until glLinkProgram is called. After a program object has been linked successfully, the index values for generic attributes remain fixed (and their values can be queried) until the next link command occurs.

This details that the binding do not go into effect until after linking your shader program.

It may also be useful to point out that

Active attributes that are not explicitly bound will be bound by the linker when glLinkProgram is called.

From experience they seem to be bound in no particular order and so this is generally why attribute 0 can go un-enabled (in my case by assuming that the first user-defined attribute in the vertex shader would be bound to attribute 0).

发布评论

评论列表(0)

  1. 暂无评论