問題の説明
私は現在、ディファード レンダラーにポイント ライトを実装していますが、ライトの境界付近でのみ目立つ重いピクセル化/三角測量がどこから来ているのかを判断するのに苦労しています。
この問題は、どこかで精度が失われたことが原因のようですが、正確な原因を突き止めることはできませんでした。法線は明らかな可能性ですが、directx を使用している同級生がいて、法線を同様の方法で問題なく処理しています。
ゲームのユニット (64 ユニット/メートル) で約 2 メートル離れたところから:
数センチ離れて。「ピクセル化」は、世界に近づいてもサイズが変わらないことに注意してください。ただし、カメラの向きを変えると泳いでいるように見えます。
RGBA8 レンダー ターゲットで予想される球状のバンディングを示すフォワード レンダラーのクローズ アップとの比較 (各色の値は 0 ~ 255 のみ)。私の延期された写真では、後壁が通常の球状のバンディングを示していることに注意してください。
ライト ボリュームは、緑色のワイヤフレームで示されています。
ご覧のとおり、表面に近づかない限り効果は見えません (ゲームの単位で約 1 メートル)。
位置再構築
まず、光が重なる画面の部分のみをレンダリングするために使用している球状メッシュを使用していることに言及する必要があります。ここで提案されているように、深度が深度バッファー以上の場合、背面のみをレンダリングします。
フラグメントのカメラ空間位置を再構築するために、ライト ボリュームのカメラ空間フラグメントからベクトルを取得し、それを正規化し、gbuffer からの線形深度でスケーリングしています。これは、ここで説明した方法(線形深度を使用)とここ (球状のライト ボリューム)のハイブリッドのようなものです。
ジオメトリ バッファ
私のgBufferの設定は次のとおりです。
enum render_targets { e_dist_32f = 0, e_diffuse_rgb8, e_norm_xyz8_specpow_a8, e_light_rgb8_specintes_a8, num_rt };
//...
GLint internal_formats[num_rt] = { GL_R32F, GL_RGBA8, GL_RGBA8, GL_RGBA8 };
GLint formats[num_rt] = { GL_RED, GL_RGBA, GL_RGBA, GL_RGBA };
GLint types[num_rt] = { GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT };
for(uint i = 0; i < num_rt; ++i)
{
glBindTexture(GL_TEXTURE_2D, _render_targets[i]);
glTexImage2D(GL_TEXTURE_2D, 0, internal_formats[i], _width, _height, 0, formats[i], types[i], nullptr);
}
// Separate non-linear depth buffer used for depth testing
glBindTexture(GL_TEXTURE_2D, _depth_tex_id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, _width, _height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);