Pregunta

When I write Processing.js in the JavaScript-flavor I get a performance warning that I didn't get when I used Processing.js to parse Processing-Code. I've create a fairly simple sketch with 3d support to get into it and the console is flooded with this warning:

PERFORMANCE WARNING: Attribute 0 is disabled. This has signficant performance penalty

What does that mean? And even more importantly: how to fix it?

That's the sketch. (watch/edit on codepen.io)

var can = document.createElement("canvas");
var sketch = function(p){

  p.setup = function(){
    p.size(800, 600, p.OPENGL);
    p.fill(170);
  };

  p.draw = function(){
    p.pushMatrix();
    p.translate(p.width/2, p.height/2);
    p.box(50);
    p.popMatrix();
  };
};

document.body.appendChild(can);
new Processing(can, sketch);
¿Fue útil?

Solución

This is an issue in Processing.js

For detailed explanation: OpenGL and OpenGL ES have attributes. All attributes can either fetch values from buffers or provide a constant value. Except, in OpenGL attribute 0 is special. It can not provide a constant value. It MUST get values from a buffer. WebGL though is based on OpenGL ES 2.0 which doesn't have this limitation.

So, when WebGL is running on top of OpenGL and the user does not use attribute 0 (it's set to use a constant value), WebGL has to make a temporary buffer, fill it with the constant value, and give it to OpenGL. This is slow. Hence the warning.

The issue in Processing is they have a single shader that handles multiple use cases. It has attributes for normals, positions, colors, and texture coordinates. Depending on what you ask Processing to draw it might not use all of these attributes. For example commonly it might not use normals. Normals are only needed in Processing to support lights so if you have no lights there are no normals (I'm guessing). In that case they turn off normals. Unfortunately if normals happens to be on attribute 0, in order for WebGL to render it has to make a temp buffer, fill it with a constant value, and then render.

The way around this is to always use attribute 0. In the case of Processing they will always use position data. So before linking their shaders they should call bindAttribLocation

// "aVertex" is the name of the attribute used for position data in
// Processing.js
gl.bindAttribLocation(program, 0, "aVertex");

This will make the attribute 'aVertex' always use attrib 0 and since for every use case they always use 'aVertex' they'll never get that warning.

Ideally you should always bind your locations. That way you don't have to query them after linking.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top