GLSL:数据失真

GLSL: Data Distortion

我使用的是 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) ;

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

你在这里做的是无效 OpenGL/GLSL 3.30.

让我引用 GLSL 3.30 specification 第 4.1.7 节 "Samplers"(强调我的):

Samplers aggregated into arrays within a shader (using square brackets [ ]) can only be indexed with integral constant expressions (see section 4.3.3 “Constant Expressions”).

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

从 GL 4.0 开始,这有点放松。 GLSL 4.00 specification 现在声明如下(仍然是我的重点):

Samplers aggregated into arrays within a shader (using square brackets [ ]) can only be indexed with a dynamically uniform integral expression, otherwise results are undefined.

动态统一定义如下:

A fragment-shader expression is dynamically uniform if all fragments evaluating it get the same resulting value. When loops are involved, this refers to the expression's value for the same loop iteration. When functions are involved, this refers to calls from the same call point.

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

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