私は独自のソフトウェア3dラスタライザを作成する必要があります。これまでのところ、三角形で作られた3dモデルを2d空間に投影できます。
ポイントを回転、移動、投影して、各三角形の2D空間表現を取得します。次に、3つの三角形のポイントを取り、スキャンラインアルゴリズムを実装して(線形補間を使用)、三角形のエッジ(左と右)に沿ってすべてのポイント[x] [y]を見つけて、三角形を水平にスキャンできるようにします。行ごとに、ピクセルで塗りつぶします。
これは機能します。ただし、zバッファリングも実装する必要があります。これは、三角形の3つの頂点の回転および変換されたz座標がわかっているため、スキャンラインアルゴリズムで見つけた他のすべての点のz座標を補間する必要があることを意味します。
概念は十分にはっきりしているように見えます。私はまずこれらの計算でZaとZbを見つけます。
var Z_Slope = (bottom_point_z - top_point_z) / (bottom_point_y - top_point_y);
var Za = top_point_z + ((current_point_y - top_point_y) * Z_Slope);
次に、各Zpに対して水平方向に同じ補間を行います。
var Z_Slope = (right_z - left_z) / (right_x - left_x);
var Zp = left_z + ((current_point_x - left_x) * Z_Slope);
そして、現在のzがそのインデックスで以前のzよりもビューアに近い場合は、カラーをカラーバッファに書き込み、新しいzをzバッファに書き込みます。(私の座標系はx:左->右、y:上->下、z:あなたの顔->コンピュータ画面です;)
問題は、それが問題になることです。プロジェクトがここにあり、「Z-Buffered」ラジオボタンを選択すると、結果が表示されます(「Z-Buffered」モードでは、ペインターのアルゴリズム(ワイヤフレームを描画する場合のみ)を使用していることに注意してください)デバッグ用)
PS:補間する前にzを逆数(つまり)に変換する必要があることをここで読みましたz = 1/z
。試してみましたが、変化はないようです。何が欠けていますか?(正確にどこをzを1 / zに変換する必要があるか、どこに(もしそれを)元に戻すには?)
[編集]ここに、私が得たzの最大値と最小値に関するデータがあります。
max z: 1; min z: -1; //<-- obvious, original z of the vertices of the triangles
max z: 7.197753398761272; min z: 3.791703256899924; //<-- z of the points that were drawn to screen (you know, after rotation, translation), by the scanline with zbuffer, gotten with interpolation but not 1/z.
max z: 0.2649908532179404; min z: 0.13849507306889008;//<-- same as above except I interpolated 1/z instead of z.
//yes, I am aware that changing z to 1/z means flipping the comparison in the zBuffer check. otherwise nothing gets drawn.
綿密なデバッグに入る前に、誰かが私のこれまでの概念が正しいことを確認できますか?
[編集2]
Zバッファリングを解決しました。結局のところ、描画順序はまったく混乱していません。z座標が正しく計算されていました。
問題は、フレームレートを上げるために、画面上の実際のピクセルではなく、4ピクセルごとに4px / 4pxのボックスを描画していたことです。したがって、ピクセルあたり16pxを描画していましたが、zバッファーをチェックして、そのうちの1つだけを確認しました。私はそのようなおっぱいです。
TL / DR:問題はまだ残っています:Zの代わりにZの逆数(1 / zのように)をどのように/なぜ/いつ使用する必要がありますか?現在、すべてがどちらの方法でも機能するためです。(目立った違いはありません)。