WebGL警告:"属性0被禁用.这会显着降低性能"

Gla*_*eep 5 javascript html5 canvas webgl

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

[.WebGLRenderingContext]
PERFORMANCE WARNING: Attribute 0 is disabled.
This has significant performance penalty
Run Code Online (Sandbox Code Playgroud)

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

HTML:

<!DOCTYPE html>
<html>
<body>
  <canvas id="canvas" width="100" height="100"></canvas>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

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

gma*_*man 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就会警告你.


Gla*_*eep 9

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

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

  1. 在顶点着色器中为位置创建属性变量.
  2. 创建一个缓冲区对象,将其绑定到数组缓冲区,并将顶点数据写入其中.
  3. 将属性变量绑定到位置0.
  4. 将缓冲区对象分配给属性变量.
  5. 启用对属性变量的赋值.

这是特定更改的差异,这里是一个JSFiddle,演示代码在没有警告的情况下工作.


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

顶点着色器源应更改为:

attribute vec4 a_Position;
void main() {
  gl_Position = a_Position;
  gl_PointSize = 10.0;
}
Run Code Online (Sandbox Code Playgroud)

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

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);
Run Code Online (Sandbox Code Playgroud)