web-dev-qa-db-ja.com

GLSLgl_FragCoord.zの計算と設定gl_FragDepth

だから、私は詐欺師を持っています(実際の幾何学は立方体であり、おそらくクリップされており、詐欺師の幾何学はメンガースポンジです)そして私はその深さを計算する必要があります。

ワールド空間でオフセットする量はかなり簡単に計算できます。残念ながら、私はそれで深さを混乱させることに失敗して何時間も費やしました。

私が得ることができる唯一の正しい結果は私が行くときです:

gl_FragDepth = gl_FragCoord.z

基本的に、次のことができるように、gl_FragCoord.zがどのように計算されるかを知る必要があります。

  • Gl_FragCoord.zから目の空間への逆変換を行います
  • 深さの摂動を追加します
  • この摂動された深さを元のgl_FragCoord.zと同じ空間に変換し直します。

これが重複した質問のように思われる場合は、お詫び申し上げます。同様のことを扱っている他の投稿がここにたくさんあります。ただし、それらすべてを実装した後、正しく機能するものはありません。助けを得るために1つを選ぶのではなく、この時点で、それを行う完全なコードを求めています。ほんの数行である必要があります。

22
imallett

今後の参考のために、キーコードは次のとおりです。

float far=gl_DepthRange.far; float near=gl_DepthRange.near;

vec4 eye_space_pos = gl_ModelViewMatrix * /*something*/
vec4 clip_space_pos = gl_ProjectionMatrix * eye_space_pos;

float ndc_depth = clip_space_pos.z / clip_space_pos.w;

float depth = (((far-near) * ndc_depth) + near + far) / 2.0;
gl_FragDepth = depth;
32
imallett

別の将来の参考のために、これは、OpenGL4.0アプリケーションで私のために働いていたimallettによって与えられたものと同じ式です。

vec4 v_clip_coord = modelview_projection * vec4(v_position, 1.0);
float f_ndc_depth = v_clip_coord.z / v_clip_coord.w;
gl_FragDepth = (1.0 - 0.0) * 0.5 * f_ndc_depth + (1.0 + 0.0) * 0.5;

ここで、modelview_projectionは4x4モデルビュー射影行列であり、v_positionはレンダリングされるピクセルのオブジェクト空間位置です(私の場合はレイマーチャーによって計算されます)。

方程式は ウィンドウ座標このマニュアル のセクションから来ています。私のコードでは、nearは0.0であり、farは1.0であり、これはgl_DepthRangeのデフォルト値であることに注意してください。 gl_DepthRangenotの式の近距離/遠距離と同じではないことに注意してください 透視投影行列 !!唯一のトリックは0.01.0(または実際に変更する必要がある場合はgl_DepthRange)を使用することですが、私は他の深度範囲で1時間苦労していますが、それは私の(パースペクティブ)プロジェクションマトリックスでは、すでに「ベイク」されています。

このように、方程式には実際には定数による1回の乗算((far - near) / 2)と別の定数の1回の加算((far + near) / 2)が含まれていることに注意してください。 imallettのコードで必要な乗算、加算、除算(おそらく最適化コンパイラーによって乗算に変換される)と比較してください。

7
the swine