0

我正在使用 OpenGL 3.3 GLSL 1.5 兼容性。我的顶点数据遇到了一个奇怪的问题。我正在尝试将索引值传递给片段着色器,但该值似乎会根据我的相机位置而变化。

这应该很简单:我通过顶点着色器将 GLfloat 传递给片段着色器。然后我将此值转换为无符号整数。该值大部分时间都是正确的,除了片段的边缘。无论我做什么,都会出现同样的失真。为什么我的相机位置会改变这个值?即使在下面这个荒谬的例子中,tI 也异常地等于 1.0 以外的值;

uint i;
if (tI == 1.0) i = 1;
else i = 0;
vec4 color = texture2D(tex[i], t) ;

如果我发送整数数据而不是浮点数据,我会遇到完全相同的问题。我输入的顶点数据似乎并不重要。我在数据中输入的值在整个片段中不一致。失真甚至每次看起来都完全相同。

沿片段边缘的值不等于 1.0

4

1 回答 1

1

你在这里所做的在 OpenGL/GLSL 3.30 中是无效的。

让我引用GLSL 3.30 规范,第 4.1.7 节“采样器”(强调我的):

在着色器中聚合到数组中的采样器(使用方括号 [ ])只能使用整数常量表达式进行索引(请参阅第 4.3.3 节“常量表达式”)。

使用变量作为纹理的索引并不代表规范定义的常量表达式。

从 GL 4.0 开始,这有点放松。GLSL 4.00 规范现在声明如下(我仍然强调):

在着色器中聚合到数组中的采样器(使用方括号 [])只能使用动态统一的积分表达式进行索引,否则结果是未定义的

动态统一定义如下:

如果评估它的所有片段都获得相同的结果值,则片段着色器表达式是动态统一的。当涉及循环时, this 指的是同一循环迭代的表达式的值。当涉及函数时,这是指来自同一调用点的调用。

所以现在这有点棘手。如果所有片段着色器调用实际上都为该变量获得相同的值,我猜它是允许的。但尚不清楚您的代码是否能保证这一点。您还应该考虑到片段甚至可能在基元之外进行采样。

但是,您永远不应该检查浮点数是否相等。会有数值问题。我不知道你究竟想在这里实现什么,但你可能会使用一些简单的舍入行为,或者使用整数变化。您还应该在任何情况下使用flat限定符禁用值的插值(无论如何,这对于整数情况都是必需的),这将大大改善该构造的变化,使其变得动态统一。

于 2015-01-15T21:16:24.090 回答