ステンシルシャドウ-ドゥーム3エンジン-精度エラー-シャドウクラック-なぜですか?


8

最大マップサイズに関して、Doom 3エンジンの制限をテストしています。

オブジェクトがマップの原点から遠ざかるにつれて、ステンシルシャドウの精度エラーがさらに顕著になることに気づきました。

位置:-10901 -18214 -11204 例1

位置:-10802 -26483 -19383 例2

位置:-10802 -34683 -27540 例3

これらのエラーは「シャドウクラック」と呼ばれていたと思いますが、これらのアーティファクトが以前に何と呼ばれていたかはわかりません。

ほぼすべてのアーティファクトがライト/シャドウの境界に沿って表示されます-これは次のとおりです。 ここに画像の説明を入力してください

ステンシルシャドウを使用して、このタイプのグラフィックアーティファクトを見たことがありますか?彼らは何と呼ばれている?原因は何ですか?

その他の例: その他1 その他2

これは、ここにあるバニラドゥーム3エンジンです:https : //github.com/TTimo/doom3.gpl

r_useOptimizedShadows cvar(worldspawnジオメトリのシャドウボリュームを処理する)をテストしているときに、アーティファクトが消えていることに気付きました。それから私はこの関数に私の方法を働きました:

R_LinkLightSurf( &vLight->globalShadows, tri, NULL, light, NULL, vLight->scissorRect, true /* FIXME? */ );

私はこれに変更しました:

R_LinkLightSurf( &vLight->globalShadows, tri, NULL, light, NULL, vLight->scissorRect, false /* FIXME? */ );

これによりアーティファクトが取り除かれますが、今度は、worldspawnジオメトリのシャドウボリューム内にいることはないと想定しています。したがって、シャドウボリュームの内部に移動すると、そのシャドウボリュームは適切にレンダリングされません。


1
この特定の実装については不明ですが、浮動小数点はゼロから離れるほど精度を失います。
concept3d

2
同意した。7桁は、32ビット浮動小数点数(C / C ++とも呼ばれますfloat)から期待できる精度の最大値です。あなたはそれらのうちの5つを簡単に使い果たしました。en.wikipedia.org/wiki/...
snake5

@ concept3d-関連する浮動小数点数を倍精度浮動小数点数に変換すると役立つと思いますか?誰かがそれを行うための技術的なノウハウを持っているなら。レンダリング時間が長くなる場合でも。
Stepan1010 2014年

1
@glampert質問を更新しました。バニラドゥーム3エンジンです。
Stepan1010 2014年

1
シャドウボリュームの計算を変更するとどうなりますか?(たとえば、すべてのシャドウボリュームを小さな値でスケーリングします)アーティファクトはまだ表示/変更/非表示ですか?
ロイT.

回答:


3

私は最終的に解決策を見つけました-実際にはいくつかの異なる解決策。私はしませんでした視点をプログラミング、グラフィックスから成果物の実際の原因を把握-しかし、私はいくつかの解決策を見つけました。

私の質問で以前に述べたように、アーティファクトは、worldspawn静的ジオメトリ(基本的にエンジンが移動しないことを知っているジオメトリであるため、事前に事前計算される)の事前計算されたシャドウボリュームでのみ発生しているように見えました-「dmap」と呼ばれるコンソールに入力されたコマンドを使用して、シャドウボリュームおよびその他のものを-timeします。なぜそれが静的なワールドスポーンジオメトリのシャドウのみにあり、どのASEモデルやLWOモデルにもないのかはわかりませんでした。

さて、私が気づいたのは、dmapコマンドで使用できるパラメーターがたくさんあるということです。これらのパラメーターの1つは "shadowOpt"と呼ばれ、シャドウ最適化レベルを表す必要があります。このパラメーターは列挙型を設定します-いくつかの異なるシャドウ最適化レベルがあるようです:

typedef enum {
    SO_NONE,            // 0 // NOTE: I haven't tried this one yet - should test this one.
    SO_MERGE_SURFACES,  // 1 // NOTE: this was the original default one - it causes some artifacts - the ones I have been trying to fix.
    SO_CULL_OCCLUDED,   // 2 // NOTE: this one works the best - takes a bit longer - but it has alot of unnecessary print statements that could probably be removed.
    SO_CLIP_OCCLUDERS,  // 3 // NOTE: I haven't tried this one yet - but it is not used anywhere.
    SO_CLIP_SILS,       // 4 // NOTE: I haven't tried this one yet - should test this one.
    SO_SIL_OPTIMIZE     // 5 // NOTE: this one doesn't seem to work well at all - and it takes an extrememly long amount of time - was probably an expirimental version.
} shadowOptLevel_t;

オプション2-"SO_CULL_OCCLUDED"で成功しました。それはすべてのアーティファクトを修正します-実行に少し時間がかかります-しかし、この時間の多くは大量の情報をコンソールに印刷するのに費やされていると思います-これらの印刷はおそらく削減されるか、取り除かれます。

手がかりを与えてくれた場所の1つは、tr_stencilshadow.cppのコメントです。

// if we are running from dmap, perform the (very) expensive shadow optimizations
// to remove internal sil edges and optimize the caps
if ( callOptimizer ) {

ここで、「dmap」中にこの「余分な」シャドウ最適化のみを実行する場合の問題は、これらのライトのいずれかが移動された場合(これは、実行しているプロジェクトのタイプに応じて常に可能です)、デフォルトで「最適化されていない」リアルタイムのシャドウボリューム作成プロセス(移動されたライト用)とアーティファクトがそのライトに対して再表示されます。したがって、これらのアーティファクトが表示されないことを保証する唯一の方法は、これらの静的なワールドスポーンシャドウに対して非常にコストのかかる最適化プロセスを常に実行することです。実際には非常に高価であるため、適切なグラフィックスソリューションを理解できない場合は、これが絶対的な最後の手段になります。(行う場合は、必ずここにソリューションを投稿してください。)

バニラドゥーム3エンジン用の大きなマップを作成し、worldspawnジオメトリを使用するすべての人に、最適化されたシャドウボリュームのリアルタイム作成のニーズに応じて変更できるcvarを作成することをお勧めします。私はcvar r_useExpensiveShadowOptimizationsを呼び出しました-これはoxymoronのようです。例えば:

// if we are running from dmap, perform the (very) expensive shadow optimizations
// to remove internal sil edges and optimize the caps
if ( callOptimizer || r_useExpensiveShadowOptimizations.GetBool() ) {

また、マップの大きさ(およびライトが移動しない場合)に応じて、dmapの「shadowOpt」パラメーターで静的シャドウボリュームの最適化レベルを上げることをお勧めします。

したがって、基本的に、大きなマップが必要であり、シャドウアーティファクトがないことが必要なものがすべて揃っています。使用するマップを決定するだけです。リアルタイムで実行するのは非常にコストがかかります。適切なグラフィックスソリューションが見つからない場合の最後の手段としてのみ実行してください。DMAPでこれを実行すると問題が解決し、マップのコンパイルに数秒しかかかりません。


2

Doom floatはレンダリングにs(主にOpenGLの制限)を使用したため、浮動小数点の精度エラーになる可能性が非常に高いです。しかし、をいじりながらtr_stencilshadow.cpp、問題に関連している可能性があるこのコメントに気付きました(PointsOrdered()関数内):

// vectors that wind up getting an equal hash value will
// potentially cause a misorder, which can show as a couple
// crack pixels in a shadow

....

// in the very rare case that these might be equal, all that would
// happen is an oportunity for a tiny rasterization shadow crack

そうです。また、シャドウレンダリングの実装方法に関する既知の制限である可能性もあります。率直に言って、コードは非常に面倒で読みにくいので、はっきりとは言えません。詳細については、開発者にメールを送ってみてください。


1
私もそのコメントを見ました。ただし、その関数のコードをコメントアウトしてtrue(またはfalse-問題ではない)を返しただけの場合、視覚的に何の違いもないようです。メールを送った場合、開発者の誰かが反応すると思いますか?彼らはおそらく反応しないと思います。他のすべてが失敗した場合、私はそれを試すことができると思います。
Stepan1010

@ Stepan1010わかりません、カーマックはかっこいい男です。プログラミングに関係のないことをメールで送ったところ、彼は返信しました。CarmackはidSoftwareのメンバーではなくなったので、レポジトリのメンテナにメールする必要があるかもしれません。あなたが正当な問題とあなたがした仕事を見せれば、彼らは興味を持つかもしれません。
2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.