WebGL - 使用任意二进制数据的纹理和浮点错误

时间:2017-07-09 17:17:11

标签: webgl shader

我正在使用WebGL浮点纹理来存储矩阵。 每行有N个矩阵。

在着色器中,根据每个向量的相对大小和每个纹理行,我得到这些矩阵。

例如,如果我每行有10个矩阵和10行,则着色器得到:

u_vector_size = 1 / (10 * 4)
u_row_size = 1 / 10

根据这些信息,我从纹理中获取4个像素:

uniform sampler2D u_boneMap;
uniform float u_vector_size;
uniform float u_row_size;

mat4 boneAtIndex(float column, float row) {
    column *= u_vector_size * 4.0;
    row *= u_row_size;

    return mat4(texture2D(u_boneMap, vec2(column, row)),
                texture2D(u_boneMap, vec2(column + u_vector_size, row)),
                texture2D(u_boneMap, vec2(column + u_vector_size * 2.0, row)),
                texture2D(u_boneMap, vec2(column + u_vector_size * 3.0, row)));
}

问题?这在某些司机下无效。

我主要在Mac上看到它,但它也发生在Windows上,其中提取错误的数据,一切都变得疯狂。

我假设这是由于浮点错误。

主要是因为结果会改变我是否使用具有二维功率的纹理。 数据完全相同,只是每个矢量和行的大小相对于完整纹理大小的变化。

通常我会使用纹理缓冲区,但这是WebGL代码,WebGL只支持纹理。

有没有办法让纹理可靠且一致地使用这种类型的提取矩阵?

1 个答案:

答案 0 :(得分:0)

如果它对任何人感兴趣,实际问题确实是浮点错误。由于我在像素之间的边界上采样,即使微小的浮点误差也可能导致错误的像素被采样。解决方案是在像素的中间进行采样。

uniform sampler2D u_boneMap;
uniform float u_vector_size;
uniform float u_row_size;

mat4 boneAtIndex(float column, float row) {
    column *= u_vector_size * 4.0;
    row *= u_row_size;
    column += 0.5 * u_vectorSize;
    row += 0.5 * u_rowSize;

    return mat4(texture2D(u_boneMap, vec2(column, row)),
                texture2D(u_boneMap, vec2(column + u_vector_size, row)),
                texture2D(u_boneMap, vec2(column + u_vector_size * 2.0, row)),
                texture2D(u_boneMap, vec2(column + u_vector_size * 3.0, row)));
}