ディファード シェーディング フレームワークでは、さまざまなフレーム バッファ オブジェクトを使用して、さまざまなレンダー パスを実行しています。最初のパスでは、シーン全体の をテクスチャに書き込みます。DEPTH_STENCIL_ATTACHMENT
これを と呼びましょうDepthStencilTexture
。さまざまなレンダー パスから格納されている深度情報にアクセスするにはDepthStencilTexture
、さまざまなフレーム バッファー オブジェクトを使用します。2 つの方法を知っています
。1) をシェーダーにバインドDepthStencilTexture
し、フラグメント シェーダーでアクセスします。これ
uniform vec2 WinSize; //windows dimensions
vec2 uv=gl_FragCoord.st/WinSize;
float depth=texture(DepthStencilTexture ,uv).r;
if(gl_FragCoord.z>depth) discard;
私も設定glDisable(GL_DEPTH_TEST)
し、glDepthMask(GL_FALSE)
2) をDepthStencilTexture
フレームバッファ オブジェクトにバインドしDEPTH_STENCIL_ATTACHMENT
、設定glEnable(GL_DEPTH_TEST)
しますglDepthMask(GL_FALSE)
(編集: この場合、ループ フィードバックを避けるために、シェーダにバインドしませんDepthStencilTexture
。Nicol Bolas の回答を参照してください。使用するフラグメント シェーダーgl_FragCorrd.z
)
ステンシル テストとステンシル バッファーへの書き込みが必要なライト ボリュームの描画などの特定の状況では、ソリューション 2) を使用します。ステンシルを完全に無視し、深さを に保存する必要がある他の状況では、DepthStencilTexture
オプション 1) はより「自然な」オプション 2) よりも利点がありますか?
たとえば、私は(ばかげていると思いますが)それについて疑問を持っています。フラグメント シェーダーでは、深さから WorldPosition を計算することがあります。1)の場合はこうなる
uniform mat4 invPV; //inverse PV matrix
vec2 uv=gl_FragCoord.st/WinSize;
vec4 WorldPosition=invPV*vec4(uv, texture(DepthStencilTexture ,uv).r ,1.0f );
WorldPosition=WorldPosition/WorldPosition.w;
ケース 2) の場合は次のようになります (編集: これは間違っています。gl_FragCoord.z は現在のフラグメントの深度であり、テクスチャに格納されている実際の深度ではありません)
uniform mat4 invPV; //inverse PV matrix
vec2 uv=gl_FragCoord.st/WinSize;
vec4 WorldPosition=invPV*vec4(uv, gl_FragCoord.z, 1.0f );
WorldPosition=WorldPosition/WorldPosition.w;
gl_FragCoord.z
ケース 2) はケース 1) と同じであると想定しています。texture(DepthStencilTexture ,uv).r
つまり、DepthStencilTexture
. 本当ですか?gl_FragCoord.z
現在バインドされている からDEPTH_STENCIL_ATTACHMENT
も読み取られますglDisable(GL_DEPTH_TEST)
および? glDepthMask(GL_FALSE)