2

Intel グラフィックス チップと nvidia チップでは、フラグメント シェーダの実行方法が大きく異なるという問題があります。(どちらのドライバーも最新です)

問題は、次のコードの 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ドライバーで異なる符号を返すと思うので、デバッグステートメントはポイントの符号を出力します。

最初のデバッグ出力のコメントを外すと、同じ視覚的な結果が得られます。しかし、改造後、視覚的な結果はインテル グラフィックス ドライバーと nvidia バージョンの間で異なり、非常に紛らわしいです。

誰かが私に異なる結果が得られる理由を教えてもらえますか...?

4

3 に答える 3

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)

Intel GLSL コンパイラーが、そのような型エラーを警告なしでスライドさせたことに驚いています。

また、すべてのシェーダーが適切な#versionディレクティブで開始されていることを確認してください。

于 2013-02-24T19:22:27.083 に答える
2

modは不連続なステップ関数です。 の非常に小さな変化により、 と の間で反転するp可能性があります。その結果、 の使用は丸めの詳細に非常に敏感であり、GL の実装によって異なる場合があります。OpenGL は、実装の内部数値表現で正確に表現できない結果をもたらす可能性のある補間またはその他の操作のための特定の丸め方法を規定していません。計算の最小精度要件のみを規定しています。必要に応じて、任意の実装でより高い精度を自由に使用できます。mod0cmod

したがって、おそらく起こっているのは、チップの1つが他のチップよりも高い精度を使用して計算を行っているか、1つが切り捨てられている間にもう1つが最も近い値に丸められているか、またはその他のバリエーションまたは効果の組み合わせです。

于 2013-02-24T18:57:46.507 に答える
1

0引数を使用してmod関数を呼び出します。Intelドライバーとnvidiaは異なる結果を生成します

于 2013-02-25T20:26:56.773 に答える