Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance WeblGL-用很少的CPU绘制成吨的运动图像_Performance_Image_2d_Gpu_Webgl - Fatal编程技术网

Performance WeblGL-用很少的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

我用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? 我在着色器中进行了研究,是否可以使用着色器存储纹理和坐标,然后只向着色器输入一个数组来设置我需要绘制的每个图像的位置点

谢谢,
我希望有一个简单的方法来解决这个问题。

你真的需要画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纹理。在这种情况下,必须更新对象的纹理坐标以匹配纹理
  • 使用多个纹理单位,并在着色器中决定应使用哪个单位
  • 如果有多个使用同一纹理的对象,可以对对象进行排序,以便一步绘制这些对象

是的,将有300种不同的纹理。这是我的游戏,我正计划切换到WebGL:下班后我会试试你的建议!同时,你会得到一个绿色的复选标记。我只是希望我能想出如何重用缓冲区和在着色器中使用纹理。也许或者可以帮助你改进缓冲区。这两个链接都是关于用C编写的OpenGL的。不过,将其转换为webGl应该不会太难(函数名几乎相同)。
// 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
}