Optimization 解决WebGL读取速度慢的问题

Optimization 解决WebGL读取速度慢的问题,optimization,webgl,Optimization,Webgl,我试图用WebGL来加速一个小量子电路的模拟计算,就像。我遇到的问题是,readPixels需要~10ms,但我想在动画制作过程中每帧调用它几次,以便从gpu区域获取信息,并进入javascript区域 作为一个例子,这里是我的确切用例。以下电路动画是通过计算每列门之间的状态来创建的,以显示与正在绘制的导线概率相关的内联: 按照我现在计算这些东西的方式,我需要为上述电路调用readPixels八次(每列门后一次)。这是waaaay目前太慢了,很容易采取50毫秒,当我配置它(bleh) 在这种用

我试图用WebGL来加速一个小量子电路的模拟计算,就像。我遇到的问题是,
readPixels
需要~10ms,但我想在动画制作过程中每帧调用它几次,以便从gpu区域获取信息,并进入javascript区域

作为一个例子,这里是我的确切用例。以下电路动画是通过计算每列门之间的状态来创建的,以显示与正在绘制的导线概率相关的内联:

按照我现在计算这些东西的方式,我需要为上述电路调用readPixels八次(每列门后一次)。这是waaaay目前太慢了,很容易采取50毫秒,当我配置它(bleh)

在这种用例中,加速读取像素的技巧有哪些

  • 是否存在显著影响读取像素速度的配置选项?(例如,像素格式、大小、没有深度缓冲区)
  • 在所有渲染调用完成后(可能允许一些管道),我是否应该尝试使
    readPixel
    调用同时发生
  • 我是否应该尝试将我正在阅读的所有纹理聚合到一个大纹理中,并在一次大阅读后进行排序
  • 我应该使用不同的方法从纹理中获取信息吗
  • 我是不是应该避免把信息泄露出去,做所有的布局和渲染gpu端(呃
在所有渲染调用完成后,我是否应该尝试使readPixel调用同时发生(可能允许一些管道)

对,对,对。readPixels从根本上说是一种阻塞、管道暂停操作,无论发生在哪里,它都会破坏您的性能,因为它向GPU发送数据请求,然后等待GPU响应,而正常的draw调用不必这样做

尽可能少地读取像素(使用单个组合缓冲区进行读取)。尽可能晚做。其他一切都无关紧要

我是不是应该避免把信息泄露出去,做所有的布局和渲染gpu端(呃

这将使您的性能大大提高

如果您的图形都像上面显示的那样,那么您根本不需要做任何“布局”(这很好,因为实现起来会非常困难)-除了文本之外的所有内容都是某种颜色或边界动画,可以在着色器中轻松完成,所有布局都可以只是一个静态顶点缓冲区(每个顶点都具有其应依赖于哪个点的模拟状态纹理的属性)


文本将变得更加乏味,仅仅是因为您需要将所有数字加载到纹理中以用作精灵表,并对其进行查找,但这是一种标准技术。(哦,然后除以/模以获得数字。)

我对您的用例知之甚少,只是猜测一下,为什么您需要读取像素

首先,您不需要在WebGL中绘制文本或图表的静态部分。在WebGL画布上放置另一个画布或svg或img,设置css使其重叠。让浏览器合成它们。然后您就不必这样做了

第二,假设你有一个包含计算结果的纹理。难道你就不能制作一些几何体来匹配图表中需要颜色的位置,并使用纹理坐标从结果纹理的正确位置查找结果吗?那么你根本不需要调用readPixels。该着色器可以使用渐变纹理查找或任何其他技术,将结果转换为其他颜色,以对图表的动画部分进行着色

如果希望基于可以使用的结果绘制数字,那么可以在“结果”着色器处创建一个着色器,以查看结果值,然后根据该值为另一个纹理的图示符编制索引


我说得通吗?

。每次调用总共读回多少字节?在JS land中,你需要多少值来可视化东西?@StefanHanke你的链接表明调用的速度应该比我测量的快几个数量级。作为一个webgl新手,我可能会因为配置不好而意外地减慢速度。N-线路为2^(n/2)x2^(n/2)。对于4线而言,它是一个可忽略不计的4x4,显然应该以100KHz而不是100Hz的频率运行。您可以尝试
texImage2D
texSubImage2D
。两者都有两个不同的特征码,其中一个看起来与readPixel相同。我认为值得测试它是否更快。好的,我尝试将所有内容合并到一个大纹理中,以便e只有一次读取。看起来已经足够好了。我制作了一个粗糙的“叠加纹理X覆盖纹理Y”着色器,在10量子位上执行了32次操作(因此32个着色器具有64x64输出),读取合并后的输出,其基准为~50Hz。这可能不够高,但它比使用着色器端到端更好100倍,应该更容易与现有内容集成。因为我不习惯这样做。这是一个不好的长期原因,但在短期内,这意味着我可以专注于学习一部分而不是运行深入研究并解决诸如“我如何构建事物,以便我能够知道它们是否点击了一个框,尽管坐标由着色器决定?”每小时。嗯,没有理由让着色器决定坐标。我正在尝试通过渲染多个帧缓冲区纹理来运行物理模拟,然后更新结果CPU端,然后通过交换帧缓冲区将其反馈回来。使用
readPixels()
(分析后)时,我的FPS下降到20-30 FPS,所以我想知道WebGL2在这方面是否有更好的技巧,我不知道?比如可能使用了
copyTexImage2D()
readBuffer()
?如果
drawArrays()