在OpenGL着色器中进行main之外的计算是否合理?

时间:2015-01-21 20:50:20

标签: opengl-es glsl webgl

我有一些顶点着色器代码,如下所示(这是一个简单的例子):

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让我对这个问题有点偏执 - 至少,我想了解发生了什么。

1 个答案:

答案 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常量表达式”一节定义了常量表达式。它包括:

  

以下可能用于常量表达式:

     
      
  • 制服,属性和变化。
  •   

你的案例中的表达式包括一个统一,这使它成为一个非常量表达式。因此,它不能用作全局变量的初始化器。