在 OpenGL 着色器中在 main 之外进行计算是否合理?
Is it ever reasonable to do computations outside of main in an OpenGL shader?
我有一些类似于下面的顶点着色器代码(这是一个简化的示例):
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) 使用它,它似乎在我测试过的每台机器上都能正常工作……特别是,当我更改 uViewport
变量时,viewportScale
矩阵会正确更新。这样做和在 main 函数内部进行相同的计算有什么区别吗?我找不到与此相关的任何示例或讨论。
我 运行 进入 related problem 这让我对这个问题有点厌恶 运行 -- 至少,我想了解发生了什么.
这不是 GLSL ES 1.00 中的合法着色器,它是与 ES 2.0 一起使用的 GLSL 版本。 WebGL 共享相同的 GLSL 定义,但 WebGL 规范中指定了一些例外情况。我在 WebGL 规范中找不到这个例外,所以我认为着色器在 ES 2.0 和 WebGL 中都是非法的。
来自 GLSL ES 1.00 规范,第 29 页的“4.3 存储限定符”部分(添加了重点):
Declarations of globals without a storage qualifier, or with just the const qualifier, may include initializers, in which case they will be initialized before the first line of main() is executed. Such initializers must be a constant expression.
第 49 页的“5.10 常量表达式”部分定义了常量表达式是什么。它包括:
The following may not be used in constant expressions:
- Uniforms, attributes and varyings.
你的例子中的表达式包含一个制服,这使它成为一个非常量表达式。因此它不能用作全局变量的初始值设定项。
我 运行 在我的 Android 申请中遇到了这个问题。
我在片段着色器的主块外部使用统一变量定义了一个变量。
uniform u_rotation;
mat2 rotation = mat2(cos(u_rotation), sin(u_rotation), -sin(u_rotation), cos(u_rotation));
void main() {}
这个片段着色器在除一台 Nexus 6 之外的所有 Android 设备上运行良好。奇怪的是我有两台 Nexus 6,一台每次都崩溃,另一台大部分时间都得到错误的结果。
我有一些类似于下面的顶点着色器代码(这是一个简化的示例):
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) 使用它,它似乎在我测试过的每台机器上都能正常工作……特别是,当我更改 uViewport
变量时,viewportScale
矩阵会正确更新。这样做和在 main 函数内部进行相同的计算有什么区别吗?我找不到与此相关的任何示例或讨论。
我 运行 进入 related problem 这让我对这个问题有点厌恶 运行 -- 至少,我想了解发生了什么.
这不是 GLSL ES 1.00 中的合法着色器,它是与 ES 2.0 一起使用的 GLSL 版本。 WebGL 共享相同的 GLSL 定义,但 WebGL 规范中指定了一些例外情况。我在 WebGL 规范中找不到这个例外,所以我认为着色器在 ES 2.0 和 WebGL 中都是非法的。
来自 GLSL ES 1.00 规范,第 29 页的“4.3 存储限定符”部分(添加了重点):
Declarations of globals without a storage qualifier, or with just the const qualifier, may include initializers, in which case they will be initialized before the first line of main() is executed. Such initializers must be a constant expression.
第 49 页的“5.10 常量表达式”部分定义了常量表达式是什么。它包括:
The following may not be used in constant expressions:
- Uniforms, attributes and varyings.
你的例子中的表达式包含一个制服,这使它成为一个非常量表达式。因此它不能用作全局变量的初始值设定项。
我 运行 在我的 Android 申请中遇到了这个问题。
我在片段着色器的主块外部使用统一变量定义了一个变量。
uniform u_rotation;
mat2 rotation = mat2(cos(u_rotation), sin(u_rotation), -sin(u_rotation), cos(u_rotation));
void main() {}
这个片段着色器在除一台 Nexus 6 之外的所有 Android 设备上运行良好。奇怪的是我有两台 Nexus 6,一台每次都崩溃,另一台大部分时间都得到错误的结果。