Is it ever reasonable to do computations outside of main in an OpenGL shader?

耗尽温柔 提交于 2019-12-20 02:52:52

问题


I have some vertex shader code somewhat like the following (this is a bit of simplified example):

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);
}

In particular, the viewportScale matrix is calculated from the uViewport uniform outside of the main function. Using this from a browser (WebGL), it seems to work fine on every machine I've tested on... in particular, the viewportScale matrix is correctly updated when I change the uViewport variable. Is there any difference between doing this, and doing the same calculation inside of the main function? I can't find any examples or discussion related to this.

I ran into a related problem that has made me a bit paranoid about this issue -- at the very least, I'd like to understand what's going on.


回答1:


This is not a legal shader in GLSL ES 1.00, which is the GLSL version that is used with ES 2.0. WebGL shares the same GLSL definition, with some exceptions specified in the WebGL spec. I can't find an exception for this in the WebGL spec, so I believe that the shader is illegal in both ES 2.0 and WebGL.

From the GLSL ES 1.00 spec, section "4.3 Storage Qualifiers" on page 29 (emphasis added):

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.

Section "5.10 Constant Expressions" on page 49 defines what a constant expression is. It includes:

The following may not be used in constant expressions:

  • Uniforms, attributes and varyings.

The expression in your case includes a uniform, which makes it a non-constant expression. It can therefore not be used as the initializer of a global variable.




回答2:


I ran into this problem on my Android application.

I defined a variable using an uniform variable outside of main block in a fragment shader.

uniform u_rotation;
mat2 rotation = mat2(cos(u_rotation), sin(u_rotation), -sin(u_rotation), cos(u_rotation)); 
void main() {}

This fragment shader works well on all Android devices but one Nexus 6. It is weird that I have two Nexus 6, one crashed every time and another one just got wrong result most of the time.



来源:https://stackoverflow.com/questions/28076568/is-it-ever-reasonable-to-do-computations-outside-of-main-in-an-opengl-shader

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!