我有一些顶点着色器代码,如下所示(这是一个简单的例子):
attribute vec2 aPosition;
attribute vec4 aColor;
varying lowp vec4 vColor;
uniform vec4 uViewport;
mat4 viewportScale = mat4(2.0 / uViewport.z, 0, 0, 0, 0, -2.0 / uViewport.w, 0,0, 0, 0,1,0, -1,+1,0,1);
void main() {
vec2 pos = aPosition;
gl_Position = viewportScale * vec4(pos, 0, 1);
vColor = vec4(aColor.rgb*aColor.a, aColor.a);
}
特别是,viewportScale
矩阵是根据主函数之外的uViewport
统一计算的。从浏览器(WebGL)使用它,它似乎在我测试的每台机器上都能正常工作......特别是,当我更改viewportScale
变量时,uViewport
矩阵已正确更新。这样做和在main函数中进行相同的计算有什么区别吗?我找不到任何与此相关的例子或讨论。
我遇到了related problem让我对这个问题有点偏执 - 至少,我想了解发生了什么。
答案 0 :(得分:6)
这不是GLSL ES 1.00中的合法着色器,它是与ES 2.0一起使用的GLSL版本。 WebGL共享相同的GLSL定义,WebGL规范中指定了一些例外。我在WebGL规范中找不到这个例外,所以我认为着色器在ES 2.0和WebGL中都是非法的。
从GLSL ES 1.00规范,第29页“4.3存储限定符”一节(增加重点):
没有存储限定符或仅使用const限定符的全局变量声明可能包含初始值设定项,在这种情况下,它们将在执行main()的第一行之前初始化。此类初始化程序必须是常量表达式。
第49页的“5.10常量表达式”一节定义了常量表达式。它包括:
以下可能不用于常量表达式:
- 制服,属性和变化。
你的案例中的表达式包括一个统一,这使它成为一个非常量表达式。因此,它不能用作全局变量的初始化器。