ポリゴンのラスタライザを書いていて気になったのですが、
初代プレイステーションにおいてしばしばポリゴンとポリゴンの間にわずかな隙間が空く状況が発生したようです。
これはなぜ発生するのでしょうか。
また、プレイステーションのラスタライズのアルゴリズムについての資料はありませんか?
プレイステーションの画面描画に関わるシステムは、こちらの資料などで調べたところ次のようになっているようです。
- CPU: 普通のMIPS、浮動小数点演算なし
- GTE: Geometry Transformation Engine; 16bit固定小数点数の座標演算に特化したコプロセッサ
- GPU: 整数の画面座標で2次元の3角形(または2つ繋げた4角形)を描画する
ここから、一般的なポリゴン描画ルーチンは次のようであると考えられます。
- CPUが(GTEを使ってか使わずか)モデルの座標変換行列を計算する。
- 行列をGTEにセットする。
- モデル中のあるポリゴンの頂点座標をメモリから読み、GTEに渡す。
- GTEに回転・射影変換を指示する。
- 結果を読みGPUに渡すためのメモリに書き込む。
- 同モデル中の別のポリゴンの頂点座標について、3から繰り返す
- あるモデルについて処理を終えたら、次のモデルについて、1から繰り返す
この流れで、
- 隣り合うポリゴンで共有される頂点の座標は、GTEにおいてポリゴンごとに計算されるので同じ頂点が複数回計算されますが、計算に使われる行列が途中で変更されなければ、毎回の計算で同じ入力に対して異なる出力になるとは思えません。
(行列が途中で変更される理由は無いと思うのですが、後述の情報で変更されるかのような記述があり不審です)
- GPUに隣り合うポリゴンの頂点座標として同じ値が渡った場合、ラスタライズされたとき隙間が開くとは思えません。
(ラスタライズのアルゴリズムが分からないのでここは怪しいところです)
- あとはそもそも入力データがポリゴンごとに頂点位置が異なっている可能性ですが、これはこれで考えにくいです。
(どのようなモデリングをしたらそのようなデータができる?・後処理でわずかに異なる頂点を一致させるのは簡単では?・ミスなのだからデバッグで発見して修正しないのか?・頂点座標をポリゴンごとに持つのはデータの無駄では?)
というわけで、いくつか不審な点はあるもののポリゴンに隙間が空く現象が起こる明確な理由が分かりません。
何か情報がないかと検索してみましたが有用な情報は得られませんでした。
I mean, how do you have a hole between two adjacent triangles, integer or not?
https://boards.fireden.net/v/thread/402698553/
→自分と同様の疑問(意味のある回答は無し)。
頂点計算の精度が十分では無かったので隙間が出来る
https://srad.jp/comment/2722716
GTEの演算誤差(当時の半導体プロセスの制約から浮動小数点演算の実装は困難であり、高速化のために整数演算を用いている)の影響で、ポリゴンの間にPS特有の「継ぎ目」ができる。
https://ja.wikipedia.org/wiki/PlayStation_(ゲーム機)
It is caused by errors in rounding numbers due to minimal accuracy in the PSX's hardware polygon generator .
http://www.shinforce.com/saturn/information/3D-Capabilities.htm
→整数精度のせいだとするよくある説明。整数であろうとなかろうと、同じ座標を共有するポリゴン間に隙間が空くとは思えない。
polygonal surfaces seem to wobble around, showing gaps between polygons
http://www.futuretech.blinkenlights.nl/tex.html
→ポリゴンの頂点位置のぶれと隙間を同一視している文章。ぶれる理由は隙間が空く理由にはならない。精度を理由とする説明はこれと同様の論理か。
プレステに特有の「ポリゴンの間に隙間ができる」という問題は、頂点の共有などを行っていないことに起因します。
https://www.wizforest.com/OldGood/saturn/polygon.html
→実際、頂点の共有は(ハードウェア的には)行われておらずポリゴンごとに3頂点を渡す形になりそうである。しかし共有を行わないと頂点の位置が変わる理由は分からない。
Yes, there were ways to avoid it (shared vertex calculations)
because each vertex was positioned with different transformation matrices
https://news.ycombinator.com/item?id=14013735
→異なる変換行列を使うためという説。これが最も理由として成り立っているが、異なる変換行列が使われる理由が分からない。
I have to say that it's much improved than the initial release. There're no "seams" everywhere in the ground anymore
"Vertex Caching" isn't necessary for this game anymore, but it does "close" some openings between polygons that still happen in some parts.
https://www.ngemu.com/threads/pcsxr-pgxp.186369/page-29
→エミュレータの話で、元隙間が空いていたソフトについて、頂点キャッシュは隙間を閉じる効果があるようだ。やはり頂点の共有がポイントになっていそうである。
the PSX doesn't render the rightmost pixel or bottom row of the triangle
and the way the triangle is rendered (in one or two passes, and the direction of each pass, i.e. top->bottom, bottom->top) depends on the shape of the left edge of the triangle
http://www.psxdev.net/forum/viewtopic.php?t=627
→レンダリングアルゴリズムについて。右端と下辺を描かないのは普通。左端の辺の形状によって向きが変わるというのは他で聞かない内容で、何かに影響するかもしれない。より詳しいアルゴリズムが知りたいが見つからない。これについても情報が欲しい。
回答はいつまでも求めていますが、それはそうと自分でデバッグしてみようかとよくポリゴンが割れているゲームを買ってエミュレータでデバッグを試みはじめました。
何かわかれば報告するつもりです。

あなたの回答
tips
プレビュー