我想我发现了一个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;
}
如果有人找到了优雅的解决方法......
答案 0 :(得分:1)
Windows中的Chrome和Firefox的WebGL使用ANGLE实现,而{{3}}又使用DirectX作为底层API。然后,在那里使用WebGL时某些DirectX限制/警告/错误会上升并不令人意外。
你确实截断了一个浮点类型,使用T floor(T)
或T ceil(T)
来获得更有意义的结果而没有警告。
答案 1 :(得分:1)
问题是你的制服已经不多了。
48 mat3s + 49 mat4s + 2 bools = 1218值/ 4 =至少需要306个均匀载体
在我的GPU上gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS)仅返回254.
请注意,306均匀向量用于完美优化GLSL编译器。对于未经优化的编译器,它可能在内部使用3个vec4s用于mat3,并且每个bool使用完整的vec4,这使得它需要更均匀的向量。
似乎是这种情况,因为如果我将MATRIX_ARRAY_SIZE降低到35并且它在我的机器上运行并且36失败。
35个mat3,每个使用3个载体+ 36个mat4,每个使用4个载体+ 2个bool,每个使用1个载体= 249个载体。另外,36需要257,这比我的GPU驱动程序支持的多3,这就是它失败的原因。
注128是需要支持的顶点均匀矢量的最小数量,这意味着如果你希望它能在任何地方工作,你需要将MATRIX_ARRAY_SIZE设置为17.另一方面,我不知道你是什么制服在片段着色器中使用。或者,您可以查询支持的统一向量的数量,并在运行时修改着色器源。
这是一个适合我的样本 http://jsfiddle.net/greggman/474Et/2/
将顶部的35更改回48,它将生成相同的错误消息。
很糟糕,错误信息很神秘。
答案 2 :(得分:0)
这应该在ANGLE revision 1557中修复。此修复程序需要一段时间才能在主流Chrome中使用。