我可以启动空白变量并在之后声明它们吗?
Am I able to initiate blank variables and declare them afterwards?
我想做这样的事情:
vec4 text;
if (something){
text = texture(backgroundTexture, pass_textureCoords);
}
if (somethingElse){
text = texture(anotherTexture, pass_textureCoords);
}
这是有效的 GLSL 代码吗?如果不是,是否有合适的替代方法?
答案取决于 something
和 somethingElse
实际上是什么。
如果这是一个统一的控制流,这意味着所有着色器调用都执行同一个分支,那么这是完全有效的。
如果是非统一表达式,则有一些限制:
When a texture uses mipmapping or anisotropic filtering of any kind, then any texture function that requires implicit derivatives will retrieve undefined results.
总结一下:是的,这是完全有效的 glsl 代码,但非均匀控制流中的纹理有一些限制。可在 here.
中找到更多详细信息
旁注:在代码示例中,您之后没有声明变量。你只是在给它们赋值。
编辑(更多信息)
详细说明什么是统一和非统一控制流:着色器(通常)可以有两种类型的输入。统一变量如 uniform vec3 myuniform;
和变量如 in vec3 myvarying
。不同之处在于数据的来源以及调用期间数据的变化方式:
- 制服是从应用程序端设置的,并且(因此)在一次调用中保持不变(其中调用简化意味着绘制命令)。
- 从顶点输入(在顶点着色器中)读取变量,或者从先前的着色器阶段(例如在片段着色器中)传递和插值。
统一控制流现在意味着,相应的 if 语句的条件 仅 取决于统一。其他一切都是非统一控制流。让我们看一下这个片段着色器示例:
//Uniforms
uniform vec3 my_uniform;
uniform sampler2D my_sampler;
/Varyings
in vec2 tex_coord;
in vec2 ndc_coords;
void main()
{
vec3 result = vec3(0,0,0);
if (my_uniform.y > 0.5) //Uniform control flow
result += texture(my_sampler, tex_coord).rgb;
if (ndc_coords.y > 0.5) //Non-uniform control flow
result += texture(my_sampler, tex_coord).rgb;
float some_value = ndc_coords.y + my_uniform.y;
if (some_value > 0.5) //Still non-uniform control flow
result += texture(my_sampler, tex_coord).rgb;
}
在此着色器中,只有第一个纹理读取发生在统一控制流中(因为 if 条件仅取决于统一变量)。其他两个读取处于非统一控制流中,因为 if 条件也取决于变化的 (ndc_coords
).
我想做这样的事情:
vec4 text;
if (something){
text = texture(backgroundTexture, pass_textureCoords);
}
if (somethingElse){
text = texture(anotherTexture, pass_textureCoords);
}
这是有效的 GLSL 代码吗?如果不是,是否有合适的替代方法?
答案取决于 something
和 somethingElse
实际上是什么。
如果这是一个统一的控制流,这意味着所有着色器调用都执行同一个分支,那么这是完全有效的。
如果是非统一表达式,则有一些限制:
When a texture uses mipmapping or anisotropic filtering of any kind, then any texture function that requires implicit derivatives will retrieve undefined results.
总结一下:是的,这是完全有效的 glsl 代码,但非均匀控制流中的纹理有一些限制。可在 here.
中找到更多详细信息旁注:在代码示例中,您之后没有声明变量。你只是在给它们赋值。
编辑(更多信息)
详细说明什么是统一和非统一控制流:着色器(通常)可以有两种类型的输入。统一变量如 uniform vec3 myuniform;
和变量如 in vec3 myvarying
。不同之处在于数据的来源以及调用期间数据的变化方式:
- 制服是从应用程序端设置的,并且(因此)在一次调用中保持不变(其中调用简化意味着绘制命令)。
- 从顶点输入(在顶点着色器中)读取变量,或者从先前的着色器阶段(例如在片段着色器中)传递和插值。
统一控制流现在意味着,相应的 if 语句的条件 仅 取决于统一。其他一切都是非统一控制流。让我们看一下这个片段着色器示例:
//Uniforms
uniform vec3 my_uniform;
uniform sampler2D my_sampler;
/Varyings
in vec2 tex_coord;
in vec2 ndc_coords;
void main()
{
vec3 result = vec3(0,0,0);
if (my_uniform.y > 0.5) //Uniform control flow
result += texture(my_sampler, tex_coord).rgb;
if (ndc_coords.y > 0.5) //Non-uniform control flow
result += texture(my_sampler, tex_coord).rgb;
float some_value = ndc_coords.y + my_uniform.y;
if (some_value > 0.5) //Still non-uniform control flow
result += texture(my_sampler, tex_coord).rgb;
}
在此着色器中,只有第一个纹理读取发生在统一控制流中(因为 if 条件仅取决于统一变量)。其他两个读取处于非统一控制流中,因为 if 条件也取决于变化的 (ndc_coords
).