実世界の空間距離が欲しいのですが、実験から感じたのは
(gl_FragCoord.z / gl_FragCoord.w)
深さはワールド空間ですか?しかし、よくわかりません。
編集私は、このコードのスニペットを最初に見つけた場所を見つけました。どうやらそれはカメラからの実際の深度ですか?
実世界の空間距離が欲しいのですが、実験から感じたのは
(gl_FragCoord.z / gl_FragCoord.w)
深さはワールド空間ですか?しかし、よくわかりません。
編集私は、このコードのスニペットを最初に見つけた場所を見つけました。どうやらそれはカメラからの実際の深度ですか?
これは(同じ人によって)尋ねられ、別の場所で回答されました。ここで答えを言い換えて装飾しています:
OpenGL 4.3 コア プロファイル仕様 (PDF)のセクション 15.2.2 で述べられているように、gl_FragCoord.w
はです。1 / clip.w
clip.w
gl_Position
gl_FragCoord.z
通常の変換を想定して、次のプロセスによって生成されます。
clip.z = (projectionMatrix * cameraPosition).z
ndc.z = clip.z / clip.w
glDepthRange
Near /Far 値を使用して、ウィンドウ座標に変換します。win.z = ((dfar-dnear)/2) * ndc.z + (dfar+dnear)/2
.win.z
ここで、near=0、far=1 のデフォルトの深度範囲を使用して、clip-space: に関して定義できます(clip.z/clip.w)/2 + 0.5
。これを で割るgl_FragCoord.w
と、 を掛けることと同じにclip.w
なり、次のようになります。
(gl_FragCoord.z / gl_FragCoord.w) = clip.z/2 + clip.w/2 = (clip.z + clip.w) / 2
標準の射影行列を使用して、clip.z
カメラ空間 Z コンポーネントからのスケールとオフセットを表します。スケールとオフセットは、カメラの近距離/遠距離の深度値によって定義されます。clip.w
は、再び標準射影行列で、カメラ空間 Z の否定です。したがって、これらの項で方程式を再定義できます。
(gl_FragCoord.z / gl_FragCoord.w) = (A * cam.z + B -cam.z)/2 = (C * cam.z + D)
ここA
で、 とB
は近/遠に基づくオフセットとスケールを表し、C = (A - 1)/2
とD = B / 2
は
したがって、カメラまでのカメラ空間 (またはワールド空間) の距離でgl_FragCoord.z / gl_FragCoord.w
はありません。また、カメラまでのカメラ空間の平面距離でもありません。しかし、これはカメラ空間深度の線形変換です。2 つの深度値が同じ射影行列などに由来する場合は、2 つの深度値を比較する方法として使用できます。
カメラ空間 Z を実際に計算するには、行列からカメラの近く/遠くを渡し (OpenGL はすでに範囲 near/far を提供していますA
)、それらと値を計算するB
か、またはの逆数を使用する必要があります。射影行列。別の方法として、フラグメント シェーダーは頂点シェーダーで使用できるのと同じユニフォームを使用できるため、射影行列を自分で直接使用することもできます。その行列からA
および項を直接選択できます。、および。B
A = projectionMatrix[2][2]
B = projectionMatrix[3][2]
ドキュメントによると:
Available only in the fragment language, gl_FragDepth is an output variable that
is used to establish the depth value for the current fragment. If depth buffering
is enabled and no shader writes to gl_FragDepth, then the fixed function value
for depth will be used (this value is contained in the z component of
gl_FragCoord) otherwise, the value written to gl_FragDepth is used.
したがって、シェーダーの別の場所に設定しない限り、そうあるgl_FragDepth
べきです。gl_FragCoord.z
として
gl_FragCoord.w = 1.0 / gl_Position.w
そして、(おそらく) 射影行列は -z から w を取得します (最後の列が 0,0,-1,0 の場合)。
float distanceToCamera = 1.0 / gl_FragCoord.w;