根据GLSL Cookbook的一个例子,我使用的是这段代码:
vec4 Pass2(){
ivec2 pix = ivec2(gl_FragCoord.xy);
vec4 sum = texelFetch(texSampler, pix, 0) * weight[0];
for(int i = 1; i < 5; i++){
ivec2 posPixOffs = ivec2(0, pixOffset[i]);
ivec2 negPixOffs = ivec2(0, -pixOffset[i]);
sum += texelFetchOffset(texSampler, pix, 0, posPixOffs) * weight[i];
sum += texelFetchOffset(texSampler, pix, 0, negPixOffs) * weight[i];
}
return sum;
}
其中pixOffset[]
定义为
uniform int pixOffset[5] = int[](0, 1, 2, 3, 4);
和weight[]
只是应用程序客户端的uniform float
集。
texelFetch
函数会在标题中产生错误。
什么是有限的表达,为什么这不被认为是一个?
答案 0 :(得分:2)
您不应该为统一数组指定常量值。它可能有效,但它不是规范的一部分。
常量表达式如下:
const int pixOffset[5] = int[](0, 1, 2, 3, 4);
答案 1 :(得分:0)
偏移量应该是编译时常量。如果通过索引传递从常量数组获得的值,则代码通常仅在循环可以展开时才起作用,以便单个texelFetchOffset调用最终为偏移量的常量。
在Nvidia上它通常可以工作,但AMD驱动程序通常不会展开循环,可能是因为循环实现更有效。在这种情况下,偏移表达式不再是常量,并且带有texelFetchOffset的循环无法编译或链接。
答案 2 :(得分:0)
首先,在
上回答您的问题什么是常量表达式?为什么不将其视为常量表达式?
根据Khronos website,要被视为常量表达式,表达式必须遵循以下规则之一:
- 文字值。
- 一个const限定变量(不是函数参数) 使用显式初始化程序,但仅当初始化程序本身是 以下之一:
- 一个常量表达式。
- 初始化程序列表,其组成部分本身是常量表达式。初始化程序列表本身不是表达式。
- 数组的length()函数的结果,但仅当数组具有显式的大小(其大小必须为常量表达式)时。
- 大多数的结果 运算符,只要所有操作数本身都是常量 表达式。不在此列表中的运算符是任何分配 运算符(+ =等)和逗号运算符。
- 一个类型的构造函数的结果,但仅当 构造函数本身就是常量表达式。
- 任何内置函数的返回值,但前提是该函数的所有参数本身都是常量表达式。不透明类型绝不是常量表达式。请注意,当给定常量表达式作为参数时,函数dFdx,dFdy,fwidth及其粗略和精细变化将返回0。
此外,根据Uniforms的Khronos,尽管Uniforms是隐式const,但它们不是常量表达式。
如上文David Karlsson所述,将pixOffset
更改为const
应该解决:
const int PixOffset[5] = int[](0,1,2,3,4);
如果没有,那么问题是您的GPU可能没有展开for-loop
。因此,i
变量不是常数,表达式ivec2(0, PixOffset[i])
也不是常数。在这种情况下,您要么必须手动将其展开(就像我在下面做的那样),要么使用另一种策略(例如sum += texelFetch(Texture0, pix + vec2(PixOffset[i], 0), 0) * Weight[0];
)。
vec4 sum = texelFetch(textureUniform, ivec2(gl_FragCoord.xy), 0) * gaussianWeight[0];
sum += texelFetchOffset(textureUniform, ivec2(gl_FragCoord.xy), 0, ivec2( PixOffset[0], 0)) * gaussianWeight[0];
sum += texelFetchOffset(textureUniform, ivec2(gl_FragCoord.xy), 0, ivec2(-PixOffset[0], 0)) * gaussianWeight[0];
sum += texelFetchOffset(textureUniform, ivec2(gl_FragCoord.xy), 0, ivec2( PixOffset[1], 0)) * gaussianWeight[1];
sum += texelFetchOffset(textureUniform, ivec2(gl_FragCoord.xy), 0, ivec2(-PixOffset[1], 0)) * gaussianWeight[1];
...