Performance WeblGL-用很少的CPU绘制成吨的运动图像
我用Canvas元素制作了一个游戏,每一帧都有300多张图片被绘制出来,我不得不让它运行 属性向量2 a_位置; 属性向量2 a_texCoord; 均匀vec2u_分辨率; 可变矢量2 v_texCoord; void main(){ //将矩形从像素转换为0.0到1.0 vec2 zeroToOne=a_位置/u_分辨率; //从0->1转换为0->2 vec2 zeroToTwo=zeroToOne*2.0; //从0->2转换为-1->+1(剪辑空间) vec2 clipSpace=zeroToTwo-1.0; gl_Position=vec4(clipSpace*vec2(1,-1),0,1); //将texCoord传递给片段着色器 //GPU将在点之间插值该值。 v_texCoord=a_texCoord; } 精密中泵浮子; //我们的质地 均匀采样二维u_图像; //从顶点着色器传入的texCoords。 可变矢量2 v_texCoord; void main(){ gl_FragColor=纹理2D(u_图像,v_texCoord); } 它绘制300幅图像,但只需要使用普通画布的1/2 CPU。这还不算太糟,但还不够好。 我是做错了还是不必要?有没有一种方法可以通过在GPU中进行计算或缓存来简化CPU? 我在着色器中进行了研究,是否可以使用着色器存储纹理和坐标,然后只向着色器输入一个数组来设置我需要绘制的每个图像的位置点 谢谢,Performance WeblGL-用很少的CPU绘制成吨的运动图像,performance,image,2d,gpu,webgl,Performance,Image,2d,Gpu,Webgl,我用Canvas元素制作了一个游戏,每一帧都有300多张图片被绘制出来,我不得不让它运行 属性向量2 a_位置; 属性向量2 a_texCoord; 均匀vec2u_分辨率; 可变矢量2 v_texCoord; void main(){ //将矩形从像素转换为0.0到1.0 vec2 zeroToOne=a_位置/u_分辨率; //从0->1转换为0->2 vec2 zeroToTwo=zeroToOne*2.0; //从0->2转换为-1->+1(剪辑空间) vec2 clipSpace=ze
我希望有一个简单的方法来解决这个问题。你真的需要画300张(不同的)图片吗?或者只有300个相同纹理的矩形?(这就是您当前正在做的事情) 通常,由于多种原因,您的代码效率很低:
- 不是一次性创建缓冲区并重用它,而是为每帧分配300个新的Float32Array数组(在
中)setRectangle()
- 不必为300个对象创建300个小缓冲区,您可以将所有顶点信息放在一个缓冲区中,然后一次绘制所有对象(仅当您不想使用不同的纹理绘制每个对象时,此方法才有效)
- 您正在切换每个对象的纹理状态(
)。与其绘制一批具有相同纹理的对象,不如一次性设置纹理glBindTexture
// called once
setup() {
// load and setup texture
// create vertex buffer object for your vertex data
// setup shader
}
// called every frame
display() {
gl.useProgram(..) // set shader
gl.bindTexture(..) // set texture
gl.bindBuffer(..) // set buffer
gl.drawArrays(0, 1800) // draw all you object in one step
}
如果您真的想用另一种纹理绘制每个对象,那么它就有点复杂了。但同样,您有多个选项可供优化:
- 在文件中组合多个纹理。例如,您可以在一个512x512纹理文件中组合16个128x128纹理。在这种情况下,必须更新对象的纹理坐标以匹配纹理
- 使用多个纹理单位,并在着色器中决定应使用哪个单位
- 如果有多个使用同一纹理的对象,可以对对象进行排序,以便一步绘制这些对象
// called once
setup() {
// load and setup texture
// create vertex buffer object for your vertex data
// setup shader
}
// called every frame
display() {
gl.useProgram(..) // set shader
gl.bindTexture(..) // set texture
gl.bindBuffer(..) // set buffer
gl.drawArrays(0, 1800) // draw all you object in one step
}