Javascript 如何在 CPU Uint8array 上重现 GLSL 浮点矩阵运算
Javascript how to reproduce GLSL floating point matrix operation on CPU Uint8array
我在 Uint8array
中有一些数据(3d x,y,z 坐标列表)。我需要对其执行一些浮点运算。 (矩阵旋转变换乘法)在此 3d 向量上。我正在使用 http://glmatrix.net/ 库进行计算。
数据来自第 3 方 API,将其打包为 Uint8Array
顶点数据以 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
构造函数中并使用 Float32Array.from
,但它似乎产生了相同的结果。
首先:考虑使用 Float32Array
作为顶点信息。否则可能会出现大问题。或者至少使用非无符号数据格式。
现在你的问题:
由于Uint8Array
是一种无符号数据格式,它只会保存正的 8 位值。所有负值都将被解释为正数(10000000
作为有符号整数是 -128
但作为无符号整数是 128
)
但我想真正的问题是另一个问题。
从代码中我假设您正在像这样保存顶点信息:
[X1,Y1,Z1,...]
或 [X1,Y1,Z1,W1,...]
自 i+=8;
以来,您的循环将以 8 的步长遍历数组。
因此,在您的脚本中至少每隔一个顶点就会被跳过。
我在 Uint8array
中有一些数据(3d x,y,z 坐标列表)。我需要对其执行一些浮点运算。 (矩阵旋转变换乘法)在此 3d 向量上。我正在使用 http://glmatrix.net/ 库进行计算。
数据来自第 3 方 API,将其打包为 Uint8Array
顶点数据以 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
构造函数中并使用 Float32Array.from
,但它似乎产生了相同的结果。
首先:考虑使用 Float32Array
作为顶点信息。否则可能会出现大问题。或者至少使用非无符号数据格式。
现在你的问题:
由于Uint8Array
是一种无符号数据格式,它只会保存正的 8 位值。所有负值都将被解释为正数(10000000
作为有符号整数是 -128
但作为无符号整数是 128
)
但我想真正的问题是另一个问题。 从代码中我假设您正在像这样保存顶点信息:
[X1,Y1,Z1,...]
或 [X1,Y1,Z1,W1,...]
自 i+=8;
以来,您的循环将以 8 的步长遍历数组。
因此,在您的脚本中至少每隔一个顶点就会被跳过。