为什么在我的游戏中WebGL比Canvas 2D慢?

为什么在我的游戏中WebGL比Canvas 2D慢?,webgl,Webgl,我正在我的游戏中添加WebGL支持,但我有一个奇怪的问题:它比在画布2D渲染模式下运行得还要慢,我不明白为什么 我在Firefox PC、Chrome PC和Chrome Android上都进行了检查,他们在web上用数百个Sprite平稳地运行WebGL演示,所以我的代码中肯定出现了错误 Firefox的profiler称整个游戏只使用了7%的资源,渲染部分只占1.2%。这只是游戏的标题屏幕,只有五个精灵可供绘制。虽然很慢 更新:Chrome的分析器显示空闲率只有4%,程序的空闲率高达93%,

我正在我的游戏中添加WebGL支持,但我有一个奇怪的问题:它比在画布2D渲染模式下运行得还要慢,我不明白为什么

我在Firefox PC、Chrome PC和Chrome Android上都进行了检查,他们在web上用数百个Sprite平稳地运行WebGL演示,所以我的代码中肯定出现了错误

Firefox的profiler称整个游戏只使用了7%的资源,渲染部分只占1.2%。这只是游戏的标题屏幕,只有五个精灵可供绘制。虽然很慢

更新:Chrome的分析器显示空闲率只有4%,程序的空闲率高达93%,渲染率为2.6%。
使用Canvas 2D时,情况大不相同,76%空闲,16%程序,2.3%用于绘图功能。
我的WebGL渲染代码中肯定存在问题

更新:Android Chrome的分析器(在JXD S5110上)总是说程序约为39%,DrawArray约为8%,bufferData约为5%,bindTexture约为3%。其他一切都可以忽略不计

如果mines的功能浪费了所有的资源,我知道该怎么办,但这里的瓶颈似乎是“程序”(浏览器本身?)和webgl方法,这两件事我无法编辑

请有人看看我的代码,告诉我我做错了什么

这是我的着色器

<script id="2d-vertex-shader" type="x-shader/x-vertex">
    attribute vec2 a_position;
    attribute vec2 a_texCoord;
    uniform vec2 u_resolution;
    uniform vec2 u_translation;
    uniform vec2 u_rotation;
    varying vec2 v_texCoord;
    void main()
    {
        // Rotate the position
        vec2 rotatedPosition = vec2(
             a_position.x * u_rotation.y + a_position.y * u_rotation.x,
             a_position.y * u_rotation.y - a_position.x * u_rotation.x);

        // Add in the translation.
        vec2 position = rotatedPosition + u_translation;

        // convert the rectangle from pixels to 0.0 to 1.0
        vec2 zeroToOne = a_position / u_resolution;

        // convert from 0->1 to 0->2
        vec2 zeroToTwo = zeroToOne * 2.0;

        // convert from 0->2 to -1->+1 (clipspace)
        vec2 clipSpace = zeroToTwo - 1.0;

        gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);

        // pass the texCoord to the fragment shader
        // The GPU will interpolate this value between points
        v_texCoord = a_texCoord;
    }
</script>

<script id="2d-fragment-shader" type="x-shader/x-fragment">
    precision mediump float;

    // our texture
    uniform sampler2D u_image;

    // the texCoords passed in from the vertex shader.
    varying vec2 v_texCoord;

    void main()
    {
         // Look up a color from the texture.
         gl_FragColor = texture2D(u_image, vec2(v_texCoord.s, v_texCoord.t));
    }
</script>
在图像的.onload函数中,我添加

var gl = liste_ctx[c] ;

this.texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this );

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

gl.bindTexture(gl.TEXTURE_2D, null);
下面是draw_sprite()函数的WebGL部分:

var gl = liste_ctx[c] ;

gl.bindTexture(gl.TEXTURE_2D, sprites[d_sprite].texture);

var resolutionLocation = gl.getUniformLocation(gl.program, "u_resolution");
gl.uniform2f(resolutionLocation, liste_canvas[c].width, liste_canvas[c].height);

gl.bindBuffer(gl.ARRAY_BUFFER, gl.posBuffer);

gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
     topleft_x , topleft_y ,
     topright_x , topright_y ,
     bottomleft_x , bottomleft_y ,
     bottomleft_x , bottomleft_y ,
     topright_x , topright_y ,
     bottomright_x , bottomright_y ]), gl.STATIC_DRAW);

gl.drawArrays(gl.TRIANGLES, 0, 6);

我做错了什么?

之所以这么慢,是因为使用了几个webgl画布,我现在只使用了一个,而且效果更好。但它仍然比Canvas2D慢一点,而且分析器说65%是空闲的,而它却像地狱一样滞后,所以我真的不明白

编辑:我想我明白了。因为我的电脑运行的是WinXP,所以无法启用WebGL的硬件加速,所以浏览器使用软件渲染,这就解释了为什么Chrome的profiler中的“程序”非常庞大。然而,硬件加速似乎适用于2d环境,这就是为什么它更快的原因。

这可能有助于:

相关链接:


  • 对于“优化次数过多”,这意味着功能参数/行为变化过多,因此Chrome必须不断对其进行重新优化。

    game.res\w、game.res\h的值是多少?它们与画布大小有什么关系?这是游戏的分辨率,宽度是900,高度是600。大多数时候我的画布都是这个尺寸,但有些(背景和前景)可能会更大,因为它们会滚动。
    var gl = liste_ctx[c] ;
    
    gl.bindTexture(gl.TEXTURE_2D, sprites[d_sprite].texture);
    
    var resolutionLocation = gl.getUniformLocation(gl.program, "u_resolution");
    gl.uniform2f(resolutionLocation, liste_canvas[c].width, liste_canvas[c].height);
    
    gl.bindBuffer(gl.ARRAY_BUFFER, gl.posBuffer);
    
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
         topleft_x , topleft_y ,
         topright_x , topright_y ,
         bottomleft_x , bottomleft_y ,
         bottomleft_x , bottomleft_y ,
         topright_x , topright_y ,
         bottomright_x , bottomright_y ]), gl.STATIC_DRAW);
    
    gl.drawArrays(gl.TRIANGLES, 0, 6);