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