2011-12-08 11 views
0

私はMonotouchとopenTKを使ってiOS用のパーティクルエンジンを書いています。私のアプローチは、各パーティクルの座標を投影し、このスクリーン位置に正確にスケーリングされたテクスチャ付き矩形を書き込むことです。3Dスプライト、正しいデプスバッファ情報を書き込む

正常に動作しますが、正しい奥行き値を計算するのに問題があり、スプライトが正しくオーバードローされ、シーンの3Dオブジェクトによってオーバードラングされるようになります。

//d=distance to projection plane 
float d=(float)(1.0/(Math.Tan(MathHelper.DegreesToRadians(fovy/2f)))); 
Vector3 screenPos=Vector3.Transform(ref objPos,ref viewMatrix, out screenPos); 
float depth=1-d/-screenPos.Z; 

を次に私はz座標として上記算出奥行き値を置く場所をスクリーン座標でtrianglestrip描画午前:

これは私が今日使用しているコードです。

結果はほぼ正確ですが、それほど正確ではありません。私は遠く離れたクリッピング・プレーンをどうにかする必要があると思う(私の場合、1は近く、10000は遠い)が、どうやってどうなるかわからない。正確な結果を得ることなく、さまざまな方法とアルゴリズムを試しました。

私はこれについていくつかの助けに感謝したいと思います。

+0

これは物事について奇妙な方法のように思えます。 ES 1.1にはポイントスプライト拡張機能が組み込まれており、ES 2.0では頂点シェーダに関連することを実行しています.CPUでこの変換を行う理由はありますか? – Tommy

+0

私はOpenGlの初心者ですので、私が厄介な方法でそれをすれば私を許してください。 :)しかし、私が理解しているように、通常のパイプラインを使用する場合は、パーティクルごとにローテーション行列を作成して、常にカメラに向かうようにする必要があります。これは私が避けたいオーバーヘッドを与えてくれます。また、あなたが直面している間にあなたを近づけている場合、そのようなカメラが看板に向くような視点効果を見たくないこともあります。私はES 2.0を使用しています。 – sinsro

+0

いいえ、幾何学的に考える必要はありません。ちょうどその点の位置を指定し、OpenGLにその点に2dの形を付けることができます。 ES 1.1のポイントスプライト拡張を使って実現できますが、2.0では頂点シェーダに組み込み出力 'gl_PointSize'を、フラグメントシェーダに組み込み入力' gl_PointCoord'を使用することができます。私は私の答えを編集して、かなり長いことを言っていました。 – Tommy

答えて

1

あなたが本当にやりたいことは、固定パイプラインを使用していない場合は、元の位置を取って、modelviewと投影、または設定したものをそのまま渡すことです。例えば、glFrustumのようにスタックを設定するための標準呼び出しの1つを使用し、それ以外の場合は、関連する式をマニュアルページから得ることができます。その後

z_clip = -((far + near)/(far - near)) * z_eye - ((2 * far * near)/(far - near)) 
w_clip = -z 

、最終的には:

z_device = z_clip/w_clip; 

EDIT:あなたはES 2.0で作業しているように、あなたが実際に完全に問題を回避することができますので、あなたのように変換したいということから直接読み込みます。 GL_POINTSとしてレンダリングするためにジオメトリを指定し、頂点シェーダで通常の変換を実行しますが、gl_PointSizeをそのポイントになるピクセルのサイズに設定します。

フラグメントシェーダでgl_PointCoordを読むと、ポイントに含まれる各フラグメントのテクスチャ座標を取得できます。単一の色を必要としない場合は、ポイントスプライトを描画できます。

+0

これははるかに効率的な方法のように見えますが、私はあなたがOpenGLのシェーダを使ってこのような点をテクスチャすることができることに気づいていませんでした。 :)しかし私は前に言及しなかったもう一つの要件があります。私はその中心点の周りにテクスチャ粒子を回転させることができる必要があります。このアプローチを使用してこれは可能ですか?また、ポイントを使用するパーティクルは非正方形になりますか? – sinsro

+0

依存テクスチャの読み込みで問題がなければ、フラグメントシェーダ内でローテーションを行うことができます(可能であれば避けるべきですが、この場合は回避するためにジオメトリコストを4倍にします)より良い解決策)、そこに円を確実に実現してください。しかし、GLからのビューポートに合わせたテクスチャ座標マッピングを使用して、常に軸に合わせた四角形を取得すると言ってもいいと思います。 – Tommy

+0

チップをありがとう。ポイントスプライトの制限(ラウンドでなければならず、テクスチャーアトラスアニメーションをサポートしていないため)では、このテクニックを使用することはできませんが、後で知ることは有益です。伝統的なビンボーディングは、私が忘れてしまったopenglでそれを行うための他の巧妙な方法がない限り、上記のような独自の問題を持っているので、私は考えている元のアプローチに固執するでしょう。 :) – sinsro

関連する問題