使用WebGL API进行数学运算

5

这个标题已经说明了一切,但我的问题是,在浏览器(例如 Google Chrome)中是否可以使用 WebGL API 来解决一些数学问题?

假设我想使用 WebGL API 相乘两个数字,这通常是可能的吗?如果是,我应该如何做到这一点?

很抱歉我没有分享任何代码,因为我没有得出任何答案。


你可能会喜欢一个将JS矩阵数学转换为可以在GPU上运行的“着色器”的库:gpujs - ecoe
2个回答

14

在WebGL中仅仅相乘两个数字并不是您想做的事情。它需要50-70个设置调用才能相乘两个数字。

如果你想将200万个数字乘以200万个其他数字,那么WebGL更适合这样做。有很多使用GPU进行计算的例子。首先,GPU所做的就是数学运算。人们最常要求它执行的任务是渲染3D或2D图形,这只是其中的一种。

您需要搜索的术语是GPGPU

有一定的技巧在于如何调整您的解决方案以配合GPU的工作方式

基本观点是WebGL从纹理读取数据并将数据写入纹理。什么是纹理?它们实际上只是值的二维数组。因此,将数据放入这些二维数组(纹理)中,使用WebGL从这些二维数组(纹理)读取数据,并将数据写入其他二维数组(纹理)。

与普通计算最大的差异是

  1. 在WebGL 1中,从纹理读取数据至少需要使用每个方向上的0.0到1.0之间的值进行寻址。为了从二维数组(纹理)中获取特定值,您必须计算其归一化坐标值(纹理坐标)。
  2. 假设xy是代表2个整数索引的ivec2,用于访问2d数组中的值(纹理),我们可以使用以下公式计算获取2d数组(纹理)中的值所需的归一化坐标:

vec2 uv = (vec2(xy) + 0.5) / textureDimensions;
vec4 value = texture2D(2dArrayOfValuesTexture, uv);

在WebGL 2中,我们不需要这样做。我们可以直接执行

vec4 value = textureFetch(2dArrayOfValuesTexture, xy, 0);
  • 您没有写入随机访问权限

    通常情况下,WebGL按顺序将数据写入目标2D数组(纹理),这可能会限制您的操作。有时会有创意性的变通方式

  • 您无法立即访问以前的计算结果。

    一般来说,如果您在计算10000个答案,您可以在任何时候引用以前的答案。换句话说,在计算第3766个答案时,您可以引用0到3765的答案。

    但是在WebGL中,除非您计算了所有答案,否则不能访问任何以前的答案。当然,一旦您计算出所有答案,您可以将这些答案传递回另一个计算中。基本上就是在一个巨大的“批量计算”过程中,答案之间不能相互引用。

  • 正如Kirill所指出的那样,还有一些限制。WebGL 1.0具有浮点纹理,因此易于获取数据。获取数据则需要更多工作,需要将答案编码为8位4通道纹理,读取结果,然后将其解码回答案,但已经有很多人在这样做了。WebGL 2将消除这个编码/解码步骤。


    这是我在Stackoverflow上接受过的最好的答案。干得好! - Afshin Mehrabani

    2
    我认为对于你的问题最准确的回答是肯定和否定。一方面,整个GPGPU(在图形处理器上进行计算)发展出使用着色器和一些技巧来解决一些模拟和数学问题。另一方面,“技巧”的部分使得这样做相当困难,并且只对一小部分问题真正有用,特别是那些受益于大规模并行计算的问题。
    据我所知,最常见的模式是使用片段着色器计算一些值到纹理中。然而,有些限制。首先,没有扩展程序,最好从WebGL中获得的是RGBA8纹理,这极大地限制了计算精度。但是,有一种扩展可以提供具有浮点颜色通道的纹理(以及如果我记得正确,渲染缓冲区)。此外,将结果复制回JS的成本可能很大。
    即将推出的WebGL2具有更多的形式,在GPU上进行计算的设施,例如变换反馈,几何着色器和更多的纹理和缓冲区格式。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接