1

我想我发现了 Windows 版本的 Chrome WebGL 实现的一个奇怪错误。将带有强制转换浮点数的着色器链接到 int 会导致“警告 X3206:向量类型的隐式截断”错误。我尝试了很多方法来避免它,但没有机会。

例如 :

int i;
vec3 u = vec3(1.5, 2.5, 3.5);
float z = u.z;

i = int(u.z): // warning X3206: implicit truncation of vector type
i = int(z):  // warning X3206: implicit truncation of vector type

奇怪的是,这个顶点程序在同一台电脑(同一张显卡)上的Linux版本上完美运行。是驱动问题吗?(我已经在两个具有相同结果的不同显卡的 Windows 版本上进行了测试)。其他奇怪的事情(对我来说):X3206 是普通的 DirectX 错误(?!)与 WebGL 有什么关系?

这是我使用并导致警告的完整着色器:

#define MATRIX_ARRAY_SIZE 48

/* vertex attributes */
attribute vec4 p;
attribute vec3 n;
attribute vec3 u;
attribute vec3 t;
attribute vec3 b;
attribute vec4 c;
attribute vec4 i;
attribute vec4 w;

/* enable vertex weight */
uniform bool ENw;

/* enable comput tangent */
uniform bool ENt;

/* eye view matrix */
uniform mat4 MEV;

/* transform matrices */
uniform mat4 MXF[MATRIX_ARRAY_SIZE];

/* transform normal matrices */
uniform mat3 MNR[MATRIX_ARRAY_SIZE];

/* varying fragment shader */
varying vec4 Vp;
varying vec3 Vn;
varying vec2 Vu;
varying vec3 Vt;
varying vec3 Vb;
varying vec4 Vc;

void main(void) {

    /* Position et Normal transform */
    if(ENw) { /* enable vertex weight */

        Vp = vec4(0.0, 0.0, 0.0, 0.0);
        Vn = vec3(0.0, 0.0, 0.0);

        Vp += (MXF[int(i.x)] * p) * w.x;
        Vn += (MNR[int(i.x)] * n) * w.x;

        Vp += (MXF[int(i.y)] * p) * w.y;
        Vn += (MNR[int(i.y)] * n) * w.y;

        Vp += (MXF[int(i.z)] * p) * w.z;
        Vn += (MNR[int(i.z)] * n) * w.z;

        Vp += (MXF[int(i.w)] * p) * w.w;
        Vn += (MNR[int(i.w)] * n) * w.w;

    } else {

        Vp = MXF[0] * p;
        Vn = MNR[0] * n;
    }

    /* Tangent et Binormal transform */
    if(ENt) { /* enable comput tangent */

        vec3 Cz = cross(Vn, vec3(0.0, 0.0, 1.0));
        vec3 Cy = cross(Vn, vec3(0.0, 1.0, 0.0));

        if(length(Cz) > length(Cy)) {
            Vt = Cz;
        } else {
            Vt = Cy;
        }

        Vb = cross(Vn, Vt); 

    } else {

        Vt = t;
        Vb = b;
    }

    /* Texcoord et color */
    Vu = u.xy;
    Vc = c;
    gl_PointSize = u.z;
    gl_Position = MEV * Vp;
}    

如果有人找到了一个优雅的解决方法......

4

3 回答 3

1

Windows 中的 Chrome 和 Firefox 的 WebGL 是使用ANGLE实现的,而 ANGLE又使用 DirectX 作为底层 API。然后,在那里使用 WebGL 时出现某些 DirectX 限制/警告/错误也就不足为奇了。

而且您确实在截断浮点类型,使用T floor(T)orT ceil(T)来获得更有意义的结果并且没有警告。

于 2012-07-04T13:57:46.913 回答
1

问题是你的制服用完了。

48 个 mat3s + 49 个 mat4s + 2 个布尔值 = 1218 个值 / 4 = 至少需要 306 个统一向量

在我的 GPU 上 gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS) 只返回 254。

请注意,306 个统一向量用于完美优化 GLSL 编译器。对于未优化的编译器,它可能在内部为 mat3 使用 3 个 vec4,为每个 bool 使用完整的 vec4,使其需要更统一的向量。

情况似乎是这样,因为如果我将 MATRIX_ARRAY_SIZE 降低到 35 并且它在我的机器上工作并且 36 失败。

35 个 mat3,每个使用 3 个向量 + 36 个 mat4,每个使用 4 个向量 + 2 个布尔,每个使用 1 个向量 = 需要 249 个向量。另外,36 需要 257,比我的 GPU 驱动程序支持的多 3,这就是它失败的原因。

注意 128 是需要支持的顶点统一向量的最小数量,这意味着如果你希望它在任何地方都可以工作,你需要将 MATRIX_ARRAY_SIZE 设置为 17。另一方面,我不知道你在使用什么统一片段着色器。或者,您可以查询支持的统一向量的数量并在运行时修改着色器源。

这是一个适合我的示例 http://jsfiddle.net/greggman/474Et/2/

将顶部的 35 改回 48,它将生成相同的错误消息。

错误消息很神秘,这很糟糕。

于 2012-07-04T15:55:13.590 回答
0

这应该在ANGLE 修订版 1557中修复。此修复程序需要一段时间才能在主流 Chrome 中可用。

于 2012-11-29T21:29:56.773 回答