函数 'texelFetchOffset' 的参数 4 必须是常量表达式
Argument 4 to function 'texelFetchOffset' must be a constant expression
按照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
函数在标题中产生错误。什么是合格的内容表达式,为什么它不被认为是内容表达式?
不应该给统一数组赋常量值。可能有用,但规格里没有。
常量表达式是这样的:
const int pixOffset[5] = int[](0, 1, 2, 3, 4);
这个偏移量应该是一个编译时常量。如果您通过索引传递从常量数组获得的值,则代码通常只有在循环可以展开时才能工作,因此单个texelFetchOffset调用最终会获得偏移量的常量。
在Nvidia上它通常工作,但AMD驱动程序通常不展开循环,可能是因为更有效的循环实现。在这种情况下,偏移量表达式不再是常量,并且使用texelFetchOffset的循环无法编译或链接。
首先回答你关于
的问题什么符合常量表达式的条件,为什么不认为它是常量表达式?
根据Khronos网站,要被视为常量表达式,表达式必须遵循以下规则之一:
- 文字值。
- const限定变量(不是函数参数)使用显式初始化式,但仅当初始化式为自身时下列之一:
- 常量表达式。
- 一个初始化列表,它的组件本身就是常量表达式。初始化列表本身不是表达式。
- 数组的length()函数的结果,但仅当数组有明确的大小时(who的大小必须是常量表达式)。
- 大多数的结果操作符,只要所有操作数本身都是常量表达式。不在此列表中的操作符是任意赋值操作符(+=等)和逗号操作符。
- 类型的构造函数的结果,但仅当构造函数的所有参数构造函数本身就是常量表达式。
- 任何内置函数的返回值,但仅当函数的所有参数本身都是常量表达式时。不透明类型从来不是常量表达式。请注意,函数dFdx, dFdy, fwidth,以及它们的粗和细的变化将返回0,当给定一个常量表达式作为参数时。
同样,根据Khronos on制服,虽然制服是隐式const,但它们不是常量表达式。
将pixOffset
更改为const
,正如David Karlsson上面所说的,应该可以修复它:
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];
...
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- 使用自动推导的 lambda 参数作为常量表达式
- 生成提升::hana::set 的常量表达式问题
- 为什么不能用常量表达式声明数组?
- 不是 lambda 函数中的常量表达式
- 函数调用在常量表达式中必须具有常量值
- 错误:constexpr 变量'struct2Var'必须由常量表达式初始化
- 如何在常量计算表达式中获取编译时错误?
- 关于在需要常量表达式的上下文中使用的glvalue常量表达式的问题
- 生成 constexpr 字符串表,不能产生常量表达式
- 整体模板参数。错误:在常量表达式中使用'this'
- 如何在满足常量表达式的同时将整数传递给指针,传递给 std::array<double、integer>?
- 编译器错误:函数调用在常量表达式中必须有一个常量值
- 错误:'new'不能出现在常量表达式中
- 我可以写出小于 -0.5 两个 ulps 的常量表达式双精度吗?
- 编译器在传递 const 变量时返回错误:模板参数不是常量表达式
- 为什么我不能在非常量表达式上使用此模板阶乘函数?
- C++ 使用变量而不是常量表达式初始化数组