私はOpenGLでシャドーマッピングを行っています。光の視点からシーンの奥行きをレンダリングするフレームバッファオブジェクトを作成しました。OpenGL - フレームバッファの深さテクスチャと色の濃さテクスチャ
glBindRenderbuffer(GL_RENDERBUFFER, color_buffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color_buffer);
glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buffer);
glGenTextures(1, &color_texture);
glBindTexture(GL_TEXTURE_2D, color_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture, 0);
glGenTextures(1, &depth_texture);
glBindTexture(GL_TEXTURE_2D, depth_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0);
これは、光のパースペクティブからシーンを通常どおりにレンダリングします。唯一の追加は、カスタムシェイダーを使ってシーンの深さを "color_texture"にレンダリングすることです。
varying vec4 screen_position;
void main()
{
screen_position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_Position = screen_position;
}
--------------
varying vec4 screen_position;
void main()
{
float depth = screen_position.z/screen_position.w;
gl_FragColor = vec4(depth, depth, depth, 1.0);
}
フルスクリーンクワッドを使用して、これらの2つのテクスチャ「color_texture」と「depth_texture」を画面に書き込むことができます。どちらも確かに奥行きマップであり、正確に見えます。今、奇妙なビットです。
オブジェクトの影を実際にレンダリングするときは、「color_texture」の奥行きはうまくいきますが、サンプリング「depth_texture」に切り替えると、奥行きはあるスケールと一定の違いによって異なります。
このサンプリングされた深さにファジーファクターの数字を追加したとき、私はそれをうまく機能させることができましたが、それは本当に難しく、ちょうど恐ろしい感じでした。
私は本当に何が間違っているのかを知ることはできません。技術的には、2つのテクスチャはサンプリング時に同一でなければなりません。私はRGBの精度のために "color_texture"を使うことができません。私は本当に切り替える必要がありますが、私の人生は深さのテクスチャが別の価値を与える理由を理解することができません。
以前は何度かシャドーマッピングをプログラムしていましたが、それは私には新しい概念ではありません。
誰もがこれにどのような光を当てることができますか?
偉大な答えをありがとう! NDCのZ値とウィンドウの深さとの違いを説明できますか?前面と近位のクリッププレーンは既に投影行列に供給されているので、確かに奥行きの範囲は違いがありませんか? [-1,1]を[0,1]にマッピングするだけですか、または浮動小数点精度のスケーリングを行うのですか?私はどのようにxとyの座標をglViewportでウィンドウ空間に拡大することができるのか理解しています。おそらく私は深みのあるものを見逃しています。 いずれにせよ多くの感謝、私は今それを動作させることができると信じています。 –
@Daniel:奥行き範囲は、NDC空間からZ位置のウィンドウ空間へのマッピングを定義します。だから 'glDepthRange(0.0、0.5)'を使うと、[0、0.5]の範囲の奥行値しか得られません。したがって、シャドウマップの比較を行う際には、奥行き範囲を尊重する必要があります。 –