2

我的问题是我的片段着色器在我的英特尔图形芯片上和在英伟达芯片上的执行方式非常不同。(两个驱动程序都是最新的)

问题似乎是以下代码中的 mod-call:

float opRep( vec3 p, vec3 c ){
  // gl_FragColor = vec4(max(0.0, sign(p.x)), max(sign(p.y), 0.0), max(sign(p.z), 0.0), 1);
  vec3 q = mod(p,c)-0.5*c;
  gl_FragColor = vec4(max(0.0, sign(q.x)), max(sign(q.y), 0.0), max(sign(q.z), 0.0), 1);
  return twistedColumn( q );
}

float distanceFromPoint(vec3 point) {
  return opRep(point, vec3(90.5, 0, 98));
}

gl_FragColor 是我的“调试”语句。调试语句打印点的符号,因为我认为 mod 函数在 diffrenet 驱动程序上返回不同的符号。

如果我取消注释第一个调试输出,我会得到相同的视觉结果。但是在mod之后,intel图形驱动程序和nvidia版本之间的视觉效果不同,这非常令人困惑。

有人可以给我一个提示,为什么我会得到不同的结果......?

4

3 回答 3

2

mod是一个不连续的阶跃函数——一个非常小的变化p会导致和mod之间的翻转。因此,任何使用都对舍入细节非常敏感,这可能因 GL 实现而异。OpenGL 没有规定任何特定的舍入方法用于插值或任何其他可能给出无法在实现的内部数字表示中精确表示的结果的操作。它只规定了计算的最低精度要求——如果愿意,任何实现都可以自由地使用更高的精度。0cmod

所以可能发生的事情是其中一个芯片在某些计算中使用比另一个更高的精度,或者一个正在向下舍入,而另一个舍入到最接近,或者其他一些变化或效果组合。

于 2013-02-24T18:57:46.507 回答
2
vec4(max(0.0, sign(q.x)), max(sign(q.y), 0.0), max(sign(q.z), 0.0), 1);
...
vec3(90.5, 0, 98)

注意那些整数常量。GLSL 不进行自动类型提升。试试这个:

vec4(max(0.0, sign(q.x)), max(sign(q.y), 0.0), max(sign(q.z), 0.0), 1.0);
...
vec3(90.5, 0.0, 98.0)

令我惊讶的是,英特尔 GLSL 编译器让像该幻灯片这样的类型错误却没有任何警告。

此外,确保所有着色器都以适当的#version指令开始。

于 2013-02-24T19:22:27.083 回答
1

您使用 0 参数调用您的 mod 函数。intel驱动和nvidia会产生不同的结果

于 2013-02-25T20:26:56.773 回答