4

というわけで、そもそもCGが苦手なんです。機能の1つが3D変換を2D「レイヤー」に適用できるGUIツールキットを実装しようとしています。(レイヤーには Z 座標が 1 つしかありません。変換前は、2 次元の軸に合わせた四角形です)

レイヤーを押し戻す 3D 変換に到達するまでは、これは非常に簡単です。ここに示すように、レイヤーを正しくレンダリングするには、レイヤーを複数のポリゴンに分割する必要があります。また、透過性を持たせることができるため、レイヤーが完全に遮られず、分割が必要になる場合があります。

これは、問題と望ましい結果を示した図です。このシナリオでは、青いレイヤー ( Bと呼びます) は赤いレイヤー ( R ) の上にあり、同じ Z 位置を持っています (ただし、BはRの後に追加されました)。このシナリオでは、Bを回転すると、その上部の 2 つのポイントは 0 よりも小さい Z インデックスを取得し、下部のポイントは 0 よりも高いインデックスを取得します (アンカー ポイントは 0 として残る唯一のポイント/ラインです)。

例

誰かがCPUでこれを行う良い方法を提案できますか? このシナリオに適した適切なアルゴリズムの実装 (C++ または C) を見つけるのに苦労しました。

編集:明確にするために、パイプラインのこの段階では、まだレンダリングはありません。各レイヤーのポリゴンのセットを作成する必要があるだけです。これは、レイヤーの変換されて隠蔽されたジオメトリを表します。次に、必要に応じてレンダリング (ソフトウェアまたはハードウェアのいずれか) が行われますが、常にそうとは限りません (たとえば、ヒット テストを行う場合)。

編集 2:これを達成するためのオプションとしてバイナリ スペース パーティショニングを検討しましたが、使用方法が不明な 1 つの実装 ( ) しか見つけることができGL2PSませんでした。BSP がどのように機能するかについては漠然とした理解がありますが、オクルージョン カリングにどのように使用できるかはわかりません。

編集 3:この段階では、色と透明度のブレンドを行うつもりはありません。ただの純粋な幾何学。透明度はレンダラーで処理でき、オーバードローも問題ありません。この場合、青いポリゴンは赤いポリゴンの下に描画できますが、より複雑なケースでは、深度の並べ替えやポリゴンの分割が必要になる場合があります (以下のような恐ろしいケースの例)。ビューポートは固定ですが、すべてのレイヤーが 3D で変形できるため、以下のようなシェイプを作成できます。

したがって、私が本当に探しているのは、レイヤーBを 2 つの青い形状に幾何学的に分割するアルゴリズムです。そのうちの 1 つは「上」に描画され、もう 1 つはRの下に描画されます。「下」の部分はオーバードローになりますが、大きな問題ではありません。したがって、Bを 2 つのポリゴンに分割するだけで、これらのポリゴンが順番に描画されるときにRをカットするように見えます。混ざる心配もありません。

円形

編集 4:この目的のために、何もレンダリングできません。これはすべて、純粋に幾何学的に行う必要があります ( 2Dポリゴンの生成)。これは私がもともと目指していたものです。

編集 5:サブシーンごとのクワッドの総数は約 30 (平均) であることに注意してください。間違いなく 100 を超えることはありません。レイヤーが 3D 変換されていない限り (この問題が発生する場所です)、レイヤーは描画される前に Z 位置でソートされた基数です。Z 位置が同じレイヤーは、追加された順に描画されます (先入れ先出し)。

元の質問で明確にしなかった場合は申し訳ありません。

4

2 に答える 2

2

「CGが苦手」でポリゴンが透過できるとしたら、CPU(ソフトウェアレンダリング)でやるのは至難の業です。

これを行う最も簡単な方法は、GPU レンダリング (OpenGL/Direct3D) と深度ピーリング テクニックを使用することです。

CPU ソリューション:

解決策#1(非常に難しい)

(このアルゴリズムの名前を忘れました)。

ポリゴン B を 2 つに分割する必要があります。たとえば、ポリゴン A をクリップ プレーンとして使用し、ペインターのアルゴリズムを使用して結果をレンダリングします。そのためには、レンダリング ルーチンを変更して、四角形ではなくテクスチャ ポリゴンを使用するようにする必要があります。 paitner のアルゴリズムを壊すことはもうありません。

大きな問題: 多数のポリゴンがある場合、このソリューションはシーンを無限の数の三角形に分割する可能性があります。また、テクスチャ レンダリング コードを自分で記述するのはあまり楽しくないため、OpenGL/Direct3D を使用することをお勧めします。

これを正しく行うのは非常に難しい場合があります。この方法は、「Francis S. Hill」による「Computer Graphics Using OpenGL 2nd edition」で議論されたと思います - 彼らの練習問題のどこかで。

Hidden Surface Removalに関するウィキペディアの記事も確認してください。

解決策 2 (簡単) :

最大 N 個の透明ピクセルとその深さを格納する多層z バッファーを実装する必要があります。

解決策 #3 (計算コストが高い) :レイ トレーシングを使用するだけです。完璧なレンダリング結果が得られます (デプス ピーリングと CPU ソリューション #2 の制限はありません) が、計算コストが高くなるため、レンダリング ルーチンを大幅に最適化する必要があります。

結論:

ソフトウェア レンダリングを実行している場合は、解決策 2 または 3 を使用してください。ハードウェアでレンダリングする場合は、深度ピーリングと同様の手法を使用するか、ハードウェアでレイトレーシングを実装します。

--編集-1--

1と2を実装するために必要な知識は「線と面の交点」です。平面を使用して (3D 空間で) 線を 2 つに分割する方法を理解していれば、レイトレーシングまたはクリッピングを簡単に実装できます。

#2 に必要な知識は、「テクスチャ付き 3D トライアングル レンダリング」(アルゴリズム) です。これはかなり複雑なトピックです。

GPU ソリューションを実装するには、シェーダーを扱う OpenGL チュートリアルをいくつか見つける必要があります。

--編集-2--

透明度は適切です。透明度を正しくするには、ペインターのアルゴリズムを使用してポリゴンを後ろから前に (最も遠いものから最も近いものへ) 描画する必要があるためです。特定の状況ではポリゴンを適切に並べ替えることができないため、分割する必要があります。または、リストされている手法のいずれかを使用する必要があります。そうしないと、特定の状況でアーティファクト/不適切にレンダリングされた画像が発生します。

透過性がない場合は、標準の zbuffer を実装するか、ハードウェア OpenGL を使用して描画できますが、これは非常に簡単な作業です。

--編集-3--

サブシーンごとのクワッドの総数は約 30 (平均) であることに注意してください。100を超えることはまずありません。

ポリゴンを分割すると、簡単に 100 を超える可能性があります。

各ポリゴンが他のすべてのポリゴンを分割するような方法でポリゴンを配置することは可能かもしれません。

現在、2^29 は 536870912 ですが、各分割時にポリゴン数が 2 倍になるような方法で 1 つのサーフェスを平面で分割することはできません。1 つのポリゴンを 29 回分割すると、最良のシナリオでは 30 個のポリゴンが得られ、分割面が平行でない場合、最悪のケースではおそらく数千個になります。

動作するはずの大まかなアルゴリズムの概要は次のとおりです。

  1. シーン内のすべての三角形のリストを準備します。
  2. 後ろ向きの三角形を削除します。
  3. 3D 空間で互いに交差するすべての三角形を見つけ、交線を使用してそれらを分割します。交線
  4. すべての三角形のすべての頂点のスクリーン空間座標を計算します。
  5. ペインターのアルゴリズムの深さで並べ替えます。
  6. 新しいプリミティブ用に追加のリストを準備します。
  7. 2D (ポスト プロジェクション) スクリーン スペースでオーバーラップする三角形を見つけます。
  8. 重なり合うすべての三角形について、それらのレンダリング順序を確認してください。基本的に、別の三角形の「下」にレンダリングされる三角形には、別の三角形の上にある部分があってはなりません。
    8.1. これを行うには、カメラの原点と三角形のエッジを使用して元の三角形をいくつかのサブ領域に分割し、領域が確立された並べ替え順序 (ペインターのアルゴリズム用に準備) に従っているかどうかを確認します。リージョンは、カメラの原点と三角形のエッジによって作成された 6 つのクリップ プレーンを使用して、既存の三角形のペアを分割することによって作成されます。ここに画像の説明を入力
    8.2. すべての領域がレンダリング順序に準拠している場合、三角形はそのままにしておきます。そうでない場合は、三角形をリストから削除し、「新しいプリミティブ」リストに追加します。
  9. 新しいプリミティブ リストにプリミティブがある場合は、リストを三角形リストとマージし、#5 に進みます。

そのアルゴリズムを見ると、なぜ誰もが最近 Z バッファーを使用するのかが容易に理解できます。

考えてみれば、これは CG を専門とする大学にとっては良いトレーニングです。あなたの学生があなたを嫌うかもしれない種類の練習.

于 2013-05-16T11:12:49.160 に答える