ポイント スプライト (Direct3D 9)
Direct3D 9 では、ポイント スプライトがサポートされているため、ポイント (パーティクル システム) の高性能レンダリングが可能です。ポイント スプライトとは、任意の形状にテクスチャーで定義されたとおりにレンダリングさせる、汎用的なポイント生成です。
- ポイント プリミティブのレンダリング制御
- ポイント サイズの計算
- ポイント レンダリング
ポイント プリミティブのレンダリング制御
Direct3D 9 は、ポイント スプライト (ポイント プリミティブ) のレンダリングを制御するための追加パラメーターをサポートしています。これらのパラメーターにより、ポイントに可変サイズを設定でき、テクスチャー マップを完全に適用できます。各ポイントのサイズは、アプリケーションで指定されたサイズと、Direct3D が計算する距離ベースの関数を組み合わせて決定されます。アプリケーションは、ポイント サイズの頂点単位の設定もでき、また、頂点単位には設定を行わず、D3DRS_POINTSIZE を設定してポイントに適用することもできます。ポイント サイズはカメラ空間単位で表現されます。ただし、アプリケーションがトランスフォーム後の柔軟な頂点フォーマット (FVF) 頂点を渡しているときは例外です。この場合、距離ベースの関数は適用されず、ポイント サイズはレンダー ターゲット上のピクセルの単位で表現されます。
ポイントのレンダリング時に計算し使用するテクスチャー座標は、D3DRS_POINTSPRITEENABLE の設定によって異なります。この値が TRUE に設定されている場合は、各ポイントがテクスチャー全体を表示するようにテクスチャー座標が設定されます。これは一般に、ポイントが 1 ピクセルより非常に大きい場合のみに使います。D3DRS_POINTSPRITEENABLE が FALSE に設定されている場合は、各ポイントの頂点テクスチャー座標がポイント全体に使われます。
ポイント サイズの計算
ポイント サイズは D3DRS_POINTSCALEENABLE によって決定されます。この値が FALSE に設定されている場合は、アプリケーションで指定されたサイズがスクリーン空間 (トランスフォーム後) サイズとして使われます。スクリーン空間で Direct3D に渡される頂点は、ポイント サイズを計算せず、指定されたポイント サイズがスクリーン空間のサイズとして解釈されます。
D3DRS_POINTSCALEENABLE が TRUE の場合は、Direct3D が、次の式に従ってスクリーン空間のポイント サイズを計算します。アプリケーションで指定されたポイント サイズは、カメラ空間単位で表現されます。
S s = Vh * S i * sqrt(1/(A + B * D e + C *( D e2 )))
この式の中の入力ポイント サイズ Si は、頂点ごとの値か、または D3DRS_POINTSIZE レンダリング ステートの値です。ポイント スケール係数 D3DRS_POINTSCALE_A、D3DRS_POINTSCALE_B、D3DRS_POINTSCALE_C は、ポイント A、B、および C によって表されます。ビューポートの高さ V h は、ビューポートを表す D3DVIEWPORT9 構造体の Height メンバーです。視点から位置座標への距離 (原点の目) De は、ポイント (Xe, Ye, Ze) の視点空間位置を取り、次の処理を実行することによって計算されます。
D e = sqrt (Xe2 + Y e2 + Z e2)
最大ポイント サイズ Pmax は、D3DCAPS9 構造体の MaxPointSize メンバーまたは D3DRS_POINTSIZE_MAX レンダリング ステートのどちらか小さい方を取って決定されます。最小ポイント サイズ Pmin は、D3DRS_POINTSIZE_MIN の値を調べることによって決定されます。つまり、最終的なスクリーン空間ポイント サイズ S は次の規則に従って決定されます。
- Ss > Pmax の場合は S = P max
- S < Pmin の場合は S = P min
- その他の場合は S = S s
ポイント レンダリング
スクリーン空間サイズ S のスクリーン空間ポイント P = ( X, Y, Z, W) は、次の 4 つの頂点を持つ四辺形としてラスター化されます。
(( X + S/2, Y + S/2, Z, W), ( X + S/2, Y - S/2, Z, W), ( X - S/2, Y- S/2, Z, W), ( X - S/2, Y + S/2, Z, W))
頂点色属性は頂点それぞれで複製されるため、各ポイントは常に一定の色でレンダリングされます。
テクスチャー インデックスの割り当ては、D3DRS_POINTSPRITEENABLE レンダリング ステート設定によって制御されます。D3DRS_POINTSPRITEENABLE が FALSE に設定されている場合は、頂点テクスチャー座標は頂点それぞれで複製されます。D3DRS_POINTSPRITEENABLE が TRUE に設定されている場合は、4 つの頂点のテクスチャー座標は次の値に設定されます。
(0.F, 0.F), (0.F, 1.F), (1.F, 0.F), (1.F, 1.F)
これを次の図に示します。
クリッピングが有効になっている場合は、次の規則に従ってポイントがクリッピングされます。シーンがレンダリングされる深度の範囲 (D3DVIEWPORT9 構造体の MinZ および MaxZ) を頂点が超えている場合、ポイントは視錘台の外に存在し、レンダリングされません。ポイント サイズを考慮に入れて、ポイントが完全に X および Y のビューポートの外に存在する場合、そのポイントはレンダリングされず、残りのポイントはレンダリングされます。ポイントの位置が X または Y のビューポートの外にあっても、部分的に表示できる場合があります。
ポイントは、ユーザー定義クリップ面に正しくクリップされる場合とそうでない場合があります。D3DCAPS9 構造体の PrimitiveMiscCaps メンバー内で D3DPMISCCAPS_CLIPPLANESCALEDPOINTS が設定されていない場合、ポイントは、頂点位置だけに基づき、ポイント サイズは無視して、ユーザー定義クリップ面にクリップされます。このとき、スケーリングされたポイントは、頂点位置がクリップ面の中にある場合は完全にレンダリングされ、頂点位置がクリップ面の外にある場合は破棄されます。アプリケーションでは、最大ポイント サイズと同じ大きさの境界ジオメトリをクリップ面に追加することで、不自然な効果の発生を防ぐことができます。
D3DPMISCCAPS_CLIPPLANESCALEDPOINTS ビットが設定されている場合は、スケーリングされたポイントは、ユーザー定義クリップ面に正確にクリップされます。
ハードウェア頂点処理は、ポイント サイズをサポートしている場合と、そうでない場合があります。たとえば、D3DCAPS9 構造体の MaxPointSize メンバーが 1.0 または 0.0 に設定されている、ハードウェア アブストラクション レイヤー (HAL) デバイス (D3DDEVTYPE_HAL) 上の D3DCREATE_HARDWARE_VERTEXPROCESSING でデバイスを作成すると、すべてのポイントは単一ピクセルになります。1.0 より小さなピクセル ポイント スプライトをレンダリングするには、FVF の TL (トランスフォーム済みライティング済み) 頂点、またはソフトウェア頂点処理 (D3DCREATE_SOFTWARE_VERTEXPROCESSING) を使う必要があり、この場合 Direct3D ランタイムがポイント スプライト レンダリングをエミュレートします。
頂点処理を実行し (MaxPointSize が1.0f より大きな値に設定された) ポイント スプライトをサポートするハードウェア デバイスは、トランスフォームされないスプライトのサイズ計算に必要であり、また TL 頂点の頂点ごとまたは D3DRS_POINTSIZE の設定を正しく行うためにも必要です。
ポイント、ライン、および三角形のレンダリング ルールの詳細については、「ラスター化ルール (Direct3D 9)」を参照してください。