2

基準: OpenGL とシェーダー (GLSL) を使用しており、最新の手法を維持しようとしています (たとえば、非推奨の概念から離れようとしています)。

非常に一般的な意味での私の質問は次のとおりです。詳細については以下を参照してください。

  1. シェーダーでは、GL_BLEND の使用時に見られる z オーダーの透明度の問題を解消するのに役立つカスタム ブレンディングを行うことができますか?
  2. ある種のフラグを「手動で」渡すことなく、描画されているプリミティブのタイプをシェーダーが知る方法はありますか?
  3. シェーダーが頂点を「無視」または「破棄」する方法はありますか (特にポイントを描画する場合)?

背景: 私のアプリケーションは、オルソ投影で線で接続された点を描画します (頂点は投影でさまざまな深さを持ちます)。プロジェクトでシェーダーを使い始めたのはつい最近のことです (非推奨の概念から離れようとしています)。標準的なブレンディングには、アルファ テストと深度テストの順序付けの問題があることを理解しています。基本的に、高い z レベルの「半透明」ピクセルが最初に描画される場合 (したがって、低い z レベルでそのピクセルに既に描画されている色とブレンドします)、次に、不透明なオブジェクトがそのピクセルで描画されますが、より低い z レベルでは深度テストにより、「より高い」z レベルで既に描画されているピクセルを変更できないため、ブレンドの問題が発生します。これを克服するには、最初に不透明なアイテムを描画し、次に半透明のアイテムを z の昇順で描画する必要があります。

さらに、速度と利便性のために、各頂点の情報を (いくつかの均一な変数と共に) シェーダーに渡し、シェーダーはその情報を使用して、特別な注意が必要な頂点のサブセットを見つけます。アプリ自体で同様の一連のロジックを実行しないと (そして動作が遅くなる)、アプリオリにそれが vericies のどのサブセットであるかを知ることはできません。したがって、すべての頂点をシェーダーに送信します。ただし、「ポイント」を描画するときは、シェーダーが決定するサブセットにないすべての頂点をシェーダーに無視させたいと思います。アルファをゼロに設定し、GL コンテキストでアルファ関数を使用して、たとえば 0.01 未満のアルファで何も描画しないようにすることで、効果を得ることができると思います。ただし、シェーダーが「この頂点を無視するだけ」と言うためのより良い、またはより「正しい」gsl 方法はありますか?

4

1 に答える 1

7

シェーダーでは、GL_BLEND の使用時に見られる z オーダーの透明度の問題を解消するのに役立つカスタム ブレンディングを行うことができますか?

並べ替え。GL 4.x クラスのハードウェア (Radeon HD 5xxx 以上、または GeForce 4xx 以上) にアクセスできる場合は、順序に依存しない透過性を実行できます。以前のバージョンにはデプス ピーリングなどの手法がありましたが、非常に高価でした。

GL 4.x クラスのバージョンでは、基本的に一連の透明なサンプルの「リンクされたリスト」を使用します。これをフルスクリーン パスで最終的なサンプル カラーに解決します。もちろん無料ではありませんが、他の OIT メソッドほど高価ではありません。あなたの場合にどれくらいの費用がかかるかは不明です。重複するピクセルの数に比例します。

最初に不透明なものを描画する必要があり、特殊なシェーダー コードを使用して透明なものを描画する必要があります。

ある種のフラグを「手動で」渡すことなく、描画されているプリミティブのタイプをシェーダーが知る方法はありますか?

いいえ。

シェーダーが頂点を「無視」または「破棄」する方法はありますか (特にポイントを描画する場合)?

一般的にはありませんが、ポイントについてはあります。ジオメトリ シェーダーは条件付きで頂点を放出できるため、任意の理由で任意の頂点を破棄できます。

ポイント以外のプリミティブの頂点を破棄することは可能ですが、そのプリミティブの解釈にも影響します。ポイントが単純な理由は、頂点プリミティブであるのに対し、三角形の頂点は完全なプリミティブではないためです。ラインを破棄することはできますが、ラインの頂点を破棄することは... 疑わしい価値があります。

そうは言っても、なぜこれをやりたいのかについてのあなたの説明は疑わしいメリットです。頂点データを本質的に「私と何かをする」かどうかを示すブール値で更新したいとします。つまり、フレームごとにデータを変更して、レンダリングする必要があるポイントとレンダリングしないポイントを指定する必要があります。

これを行うための最も簡単で効率的な方法は、レンダリングしないことです。つまり、レンダリングするポイントだけが GPU にあるようにデータを配置します。したがって、特別なことをする必要はまったくありません。頂点データを常に更新する場合は、頂点データのストリーミングを処理する必要があります。したがって、レンダリングを効率的にする方法でストリーミングすることもできます。

于 2012-06-27T18:19:52.433 に答える