グラフィックスパイプラインを使用して、密度関数に基づいてボリュメトリックデータをレンダリングするにはどうすればよいですか?


12

両方のグラフィックスAPI(OpenGLおよびDirectX)は、いくつかのステージがプログラム可能な、明確に定義されたパイプラインを考案します。これらのプログラム可能なステージは、固定された最小量のデータを取得する必要があり、データに対して適切に定義された範囲の操作を行い、定義された最小出力を出力するため、データを次のステージに正しく渡すことができます。これらのパイプラインは、限られた量のジオメトリデータのみで動作するように設計されているように見えます。D3DとOGLの両方の場合、頂点データとテクスチャ座標です。

しかし、作成しようとしているアプリケーションが幾何学的データを表すために頂点(またはボクセルさえ)を使用せず、変換や投影、ラスタライズ、補間、またはそのような何かを正確に行わない場合、APIのそのような制限またはパイプラインが物事を困難にします。

では、グラフィックスパイプラインを変更して、各ステージがデータに対して行う機能と各ステージで出力されるデータのタイプの機能を変更する方法はありますか?そうでない場合、「生の」API関数を使用して独自のパイプラインを構築する方法はありますか?そうでない場合は、それが不可能な理由を説明してください。

編集:私のアプリケーションは、密度関数を使用してジオメトリを表現します。この関数は、空間の各ポイントに値を持っています。カメラの錐台を3Dグリッドに分割し、各ブロックをピクセルとして投影できます。各ブロックで、密度関数を統合し、その値が必要な値を超えているかどうかを確認します。はいの場合、そのブロックに何かが存在し、そのブロックに対応するピクセルがレンダリングされると想定されます。だから、今私のレンダラーでは、頂点バッファーの頂点データの代わりに、関数(文字列で表す)をグラフィックスハードウェアに渡したいと思います。これは、頂点シェーダーに同種のクリップスペースに変換する頂点がなく、フラグメントシェーダーがピクセル情報を取得しないことも意味します。代わりに、ほとんどの検索と評価はピクセルごとに行われます。


「関数密度関数」はトートロジーですか?
ファラプ14

@Pharap、それはタイプミスでした。空間に「物質」が存在することを表す、単純な「desity functon」。
ライトスパーク14

2
よく研究されている問題である等値面を構築したいだけのように思えます。http.developer.nvidia.com/GPUGems3/gpugems3_ch07.htmlを見たり、メタボール、点群の視覚化、等値面の抽出、またはボリュームレンダリングで検索したことがありますか?また、どのようなパフォーマンスが必要かは、計算の複雑さと組み合わせた場合に検索する手法の選択に大きな違いをもたらします。カメラを動かすと、ピクセルごとにキラキラ光る原因になり、サブピクセルが必要になることもわかると思います。
パトリックヒューズ14

回答:


18

絶対にGPUを使用して、体積データをレンダリングできます。

画面上のピクセルごとの関数セットを評価するため、単純なアプローチは全画面の三角形をレンダリングすることです。これは、画面全体を覆う1つの三角形にすぎません(実際には、画面は三角形ではないため、画面よりも多くをカバーしますが、画面外の部分はGPUによって破棄されます)。次に、ピクセルシェーダー(シェーディングしているピクセルの画面座標を受け取る)を使用して、ボリュームを介して光線を作成し、必要な機能を評価します。

(他の回答とは対照的に、ピクセルごとの操作を行いたいように聞こえるので、コンピューティングシェーダーはお勧めしません。また、フルスクリーンの三角形+ピクセルシェーダーは、一般的にコンピューティングシェーダーよりも効率的です。計算シェーダーも確かに機能します。)

フルスクリーンの三角形の方法は、後処理操作のリアルタイムグラフィックスで非常に一般的です。そのため、必要なすべての情報を少しグーグルで見つけることができます。

ところで、フルスクリーンピクセルシェーダーテクニックを使用して数学関数(具体的には距離フィールド)を使用して構成された3Dシーンをレンダリングする方法を説明するトーク、IñigoQuílezの2つの三角形のあるレンダリングワールドを読むことをお勧めします。


ピクセルシェーダーは任意の入力(文字列または他の種類のユーザー定義オブジェクトなど)を受け取るので、関数を渡すことができますか?
ライトスパーク14

GPU上の任意のファンクション文字列でパーサーや言語を実行してみたくはありませんが、GPUは実際には汎用ではないため、扱いにくいです。ほとんどの場合、メインコードでシェーダー自体を動的に作成し、グラフィックシステムでコンパイルして、結果のシェーダーを実行します。
パトリックヒューズ14

@TheLightSpark右、シェーダーに文字列を渡さず(シェーディング言語には文字列型さえありません)、目的の機能のシェーダーコードを生成およびコンパイルする必要があります。必要に応じて、実行時に実行できます。
ネイサンリード14

あなたの答えを読み始め、私は三角形のモニターを想像しました;)ピクセルを捨てずに画面を覆う2つではなく1つの三角形のみを使用することには利点がありますか?
ダニジャー14

@danijarはい、フルスクリーンクワッドを使用すると、対角線に沿った一部のピクセルが2回シェーディングされるため、クワッドを使用するよりもわずかに利点があります。一方、ラスタライザはそもそもピクセルを生成しないため、画面外のピクセルの破棄は無料です。
ネイサンリード14

6

レイトレーシングおよびその他の手法は、一般にCompute Shadersで行われます。D3D11およびOpenGLのリリース以降4.3でサポートされていたDirect3Dは、4.3以降(およびOpenCLといくつかのゆがみの使用により)をサポートしました。


5

GPUコンピューティングシェーダーを使用するか、「シェーダーストレージバッファー」オブジェクトを使用して、パイプラインをニーズに合わせて拡張したいようです。数学者、科学者、および標準グラフィックスに正確に変換されないものの計算のためにGPUに注目する他の人々は、この種のものを使用します。

現代のグラフィックパイプラインは非常に柔軟ですが、開発者は依然としていくつかの制限につまずく傾向があります。ただし、計算シェーダー機能を使用すると、頂点とフラグメントについて考えることに慣れているため、パイプラインステージについて考える必要がなくなります。特定のパイプラインステージの入力と出力によって制限されなくなりました。たとえば、シェーダーストレージバッファーオブジェクト(SSBO)機能は、コンピューティングシェーダーと共に導入されており、パイプラインステージ間でデータを交換するための追加の可能性を提供し、コンピューティングシェーダーの柔軟な入出力を可能にします。

http://community.arm.com/groups/arm-mali-graphics/blog/2014/04/17/get-started-with-compute-shaders

これが正しい方向を向いていない場合、頂点/フラグメントのパラダイムに適合しないあなたの概念を拡大してみませんか?


回答を編集して、自分がしていることを含めました。計算シェーダーが答えのように見えますが、他に何かできることがあれば教えてください。
ライトスパーク14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.