シェーダーを作成して、影付きの円を描画することにより、ポイントスプライト上に球をレンダリングします。互いに近い球が正しく交差するように、深度コンポーネントと色を作成する必要があります。
私はJohnaHolwerdaによって書かれたものと同様のコードを使用しています:
void PS_ShowDepth(VS_OUTPUT input, out float4 color: COLOR0,out float depth : DEPTH)
{
float dist = length (input.uv - float2 (0.5f, 0.5f)); //get the distance form the center of the point-sprite
float alpha = saturate(sign (0.5f - dist));
sphereDepth = cos (dist * 3.14159) * sphereThickness * particleSize; //calculate how thick the sphere should be; sphereThickness is a variable.
depth = saturate (sphereDepth + input.color.w); //input.color.w represents the depth value of the pixel on the point-sprite
color = float4 (depth.xxx ,alpha ); //or anything else you might need in future passes
}
そのリンクのビデオは、私が求めている効果の良いアイデアを提供します。ポイントスプライトに描かれた球は正しく交差します。説明のために以下の画像を追加しました。
ポイントスプライト自体の深さを正確に計算できます。ただし、球の厚さをピクセルで計算してスプライトの深さに追加し、最終的な深さの値を与えることを示すかどうかはわかりません。(上記のコードは、変数を計算するのではなく使用します。)
私はこれを数週間オンとオフで取り組んできましたが、それを理解していません-それは単純だと確信していますが、それは私の脳が小刻みに動くことはありません。
Direct3D 9のポイントスプライトサイズはピクセル単位で計算され、私のスプライトにはいくつかのサイズがあります-距離によるフォールオフ(頂点シェーダーでポイントサイズの計算に使用された古い固定関数パイプラインと同じアルゴリズムを実装しました)と、スプライトはを表します。
ピクセルシェーダーにあるデータ(スプライトの位置、スプライトの深さ、元のワールドスペースの半径、画面上のピクセルの半径、スプライトの中心からの問題のピクセルの正規化された距離)から深さの値に移動するにはどうすればよいですか?深さ座標 でのスプライトサイズと球の厚さの単純な部分解は問題ありません。これは、中心からの正規化された距離でスケーリングして、ピクセルでの球の厚さを取得できます。
SMの上限としてシェーダーモデル3でDirect3D9とHLSLを使用しています。
写真で
テクニックと私が問題を抱えているポイントを示すために:
2つのポイントスプライトから開始し、ピクセルシェーダーで、クリップを使用して円の境界の外側のフラグメントを削除し、それぞれに円を描画します。
結局、それらは平らな表面であるため、一方が他方の上にレンダリングされます。
次に、シェーダーをさらに高度にし、照明付きの球のように円を描きます。フラットスプライトは3Dに見えますが、幻想であるため、一方をもう一方の前に完全に配置して描画することに注意してください。フラットスプライトはまだフラットです。
(上記は簡単です。これは私が問題を抱えている最後のステップであり、どのように達成するかを尋ねています。)
これで、ピクセルシェーダーがカラー値のみを書き込む代わりに、深度も書き込む必要があります。
void SpherePS (...any parameters...
out float4 oBackBuffer : COLOR0,
out float oDepth : DEPTH0 <- now also writing depth
)
{
球の間の距離が半径よりも小さい場合、球が交差することに注意してください。
この最後のステップを達成するために、正しい深度値を計算するにはどうすればよいですか?
編集/メモ
何人かの人々は、実際の球は遠近法のために歪むだろうとコメントしました。それは特に画面の端に見えるかもしれません、それで私は別のテクニックを使うべきです。まず、それを指摘してくれてありがとう、それは必ずしも明白ではなく、将来の読者にとって良いことです!次に、私の目的は、遠近法が正しい球をレンダリングすることではなく、数百万のデータポイントを高速にレンダリングすることです。視覚的には、球のようなオブジェクトはフラットスプライトよりも見栄えがよく、空間位置もよく表示されると思います。わずかな歪みや歪みの欠如は問題ではありません。デモビデオを見れば、それがどのように便利なビジュアルツールであるかを見ることができます。単純なハードウェアで生成されたポイントスプライトと比較して三角形の数が多いため、実際の球メッシュをレンダリングしたくありません。私は本当にポイントスプライトの手法を使用したいと思っています。正しい深度値を計算するために、現存するデモ手法を拡張したいだけです。デモでは、それがどのように導出されたかのソースなしで変数として渡されました。