【问题标题】:Javascript how to reproduce GLSL floating point matrix operation on CPU Uint8arrayJavascript如何在CPU Uint8array上重现GLSL浮点矩阵运算
【发布时间】:2017-09-01 12:19:06
【问题描述】:

我在Uint8array 中有一些数据(3d x,y,z 坐标列表)。我需要对其执行一些浮点运算。 (矩阵旋转变换乘法)在这个 3d 向量上。我正在使用http://glmatrix.net/ 库进行计算。

数据来自将其打包为Uint8Array 的第3 方API。顶点数据以8 个[x,y,z,w,r,g,b,a] 为一组格式化

到目前为止,我一直在 GPU 上执行此操作,将 Uint8array 和旋转矩阵传递给 GLSL。我正在将操作移至离线执行的基于 CPU 的脚本。

更新等式的另一部分。离线脚本是一个 node.js CLI 脚本,它将最终缓冲区写入标准输出,并最终使用 unix > 运算符写入文件。然后我将它加载到最终的应用程序中,并用typedArray 构造函数包装arrayBuffer

在 GLSL 中执行时,操作如下:

matrix * vec4(vert.x, vert.y, vert.z, 1.0)

我的结果如下所示:

现在在 CPU 上我当前的代码尝试是:

  const vertData = getVertDataUint8();
  const rotation = mat4.fromRotation(mat4.identity([]), -Math.PI/2, [1,0,0]);
  var i = 0;
  while(i<vertData.length){
    const rotatedVerts = vec4.transformMat4([],
                                            vec4.clone([vertData[i],vertData[i+1],vertData[i+2], 1]),
                                            rotation);

    vertData[i] = rotatedVerts[0];
    vertData[i+1] = rotatedVerts[1];
    vertData[i+2] = rotatedVerts[2];
    i+=8;
  }

我的结果如下所示:

我注意到在将值重新分配给 vertData 时,特别是负值,它们被转换为整数。例如-10 ~= 246

您可以在浏览器控制台中重现:

var u = new Uint8Array(1)
undefined
u[0] = -10
-10
u[0]
246

我尝试通过将Uint8Array 包装在Float32Array 构造函数中并使用Float32Array.fromUint8Array 转换为Float32Array,但它似乎产生了相同的结果。

【问题讨论】:

  • 首先:顶点数据请使用Float32Array。你为什么使用i+=8;?你的 UInt8Array 应该是这样的:[X1,Y1,Z1,...][X1,Y1,Z1,W1,...] 所以使用 i+=8 你至少每隔一秒跳过一次。
  • @Bellian 我应该补充一点,顶点数据来自不易更新的第 3 方源。我可以将Uint8Array 转换为Float32Array,此外,顶点格式实际上是 8 个属性的集合 [x,y,z,w,r,g,b,a] 所以以 8 步迭代是可以的

标签: javascript floating-point glsl webgl typed-arrays


【解决方案1】:

首先:考虑使用Float32Array 作为您的顶点信息。否则可能会出现大量问题。或者至少使用非无符号数据格式。

现在你的问题:

由于Uint8Array 是一种无符号数据格式,它只会保存正的 8 位值。所有负值都将被解释为正值(10000000 有符号整数是 -128,但无符号整数是 128

但我想真正的问题是另一个问题。 从代码中我假设您正在保存这样的顶点信息:

[X1,Y1,Z1,...][X1,Y1,Z1,W1,...]

您的循环将从i+=8; 开始以 8 步迭代数组。 因此,您的脚本中至少会跳过第二个顶点。

【讨论】:

  • 我更新了问题并回复了您对顶点数据格式的原始评论
  • 记录在案。我必须使用.from 方法来转换数据const vertData = Float32Array.from(getVertDataUint8());,并且在写入磁盘时我必须使用process.stdout.write(Buffer.from(vertData.buffer));
猜你喜欢
  • 2015-10-06
  • 1970-01-01
  • 2016-12-06
  • 2015-07-29
  • 2011-07-22
  • 2015-10-04
  • 1970-01-01
  • 2013-05-13
  • 1970-01-01
相关资源
最近更新 更多