OpenGL/OpenTK 内部空間の塗りつぶし 質問する

OpenGL/OpenTK 内部空間の塗りつぶし 質問する

私は、3 次元ジオメトリを色で「塗りつぶす」方法、そして将来的にはテクスチャで「塗りつぶす」方法を探しています。

仮に、物理的にコンクリートの壁に頭を突っ込むことができたとします。論理的には暗闇しか見えません。しかし、OpenGL では、これを行うと、カリングとジオメトリの描画方法により、世界は自然に空洞で透明になります。代わりに、その中の暗闇/色/テクスチャをシミュレートしたいと思います。

一部のゲームでは、テクスチャ/色を HUD 上に直接重ねて、プレイヤーの目をくらませることでこれを実現していることがわかっています。

しかし、これを実現する別の方法はあるのでしょうか? プレイヤーが半分水の中に立っているとします。プレイヤーは波の下を部分的に見ることができます。画面の半分の下がはっきりと見えないようにするには、どのように塗りつぶせばよいでしょうか?

この概念は何と呼ばれているのでしょうか?

ベストアンサー1

カメラの前にテクスチャを置く方法の問題は、テクスチャは2Dであるが、3Dボリュームのスライスを視覚化したいということです。最初にお話しした壁の中の頭のアイデアについては、「3D/ボリュームテクスチャリング」半分水の中に立っている場合は、「ボリュームレンダリング」"吸収"(@user3670102 によって議論されました)。

3Dテクスチャリング

ここでの一般的な考え方は、通常のテクスチャ マッピングのように表面だけでなく、3D 空間のあらゆる場所で色を定義する関数があるということです。ジオメトリをどこにでも配置し、フラグメント シェーダーで 3D 位置に基づいて色付けできるため便利です。ボリュームをスライスして、交差点の色を確認することを考えてみてください。

壁に頭がくっついているような効果を出すには、プレイヤーの正面にフルスクリーンのポリゴンを描き (クリッピング プレーンの近くですが、小さすぎないように少し前に押し出すといいかもしれません)、3D 関数に基づいて色付けします。これで、ポリゴンは適切に立体的に見え、プレイヤーの動きに合わせて動き、画面上に安っぽくテクスチャを貼り付けたようには見えなくなります。

ここに画像の説明を入力してください

実際の関数は 3D テクスチャで定義できますが、メモリを大量に消費します。代わりに、手続き型 3D カラー (手続き型木材またはレンガ シェーダーは、例としてかなり一般的です) を検討できます。2D テクスチャがボリュームを通して「押し出される」と仮定しても機能しますが、描画する交差/表面の角度に基づいて 3 つのテクスチャ (各軸に 1 つ) に重み付けすると、さらに効果的です。

ジオメトリとニア クリッピング プレーンの交差を検出するのが、おそらくここで最も難しい部分です。私なら、Z バッファのトリックを調べて、すべてをソリッドな非自己交差ジオメトリとして描画するようにします。単純なアイデアとしては、すべてを前面で描画した後にのみ背面を描画することが考えられます。背面が見える場合、ニア プレーンのその部分は何かの中にあるはずです。これらのピクセルに対して、ワールド空間でニア クリッピング プレーンの位置を計算し、3D テクスチャを適用できます。ただし、すべてを 2 回描画するよりも速い方法があると思います。

実際には、おそらく目に見える部分には光が届かず、黒になるはずですが、これを無視して、照明なしで直接色をレンダリングすると思います。

吸収

これは実際よりずっと難しいように思えます。もし、すべてが 1 色 (「均質」) の透明な固体があるとすると、光が通過する距離が長くなるほど光は除去されます。アルファ透明の表面を多数考え、その限界を取ると指数関数が得られます。残る光は1/exp(dist)またはに近くなりますexp(-dist)。Google で「ビールの法則」を検索してください。ここ

vec3 Absorbance = WaterColor * WaterDensity * -WaterDepth;
vec3 Transmittance = exp(Absorbance);

何かを通して距離を見つける優れた方法は、浮動小数点テクスチャまでの距離を描画するシェーダを使用して、加算ブレンディングで背面 (または海底/水底) をレンダリングすることです。次に、減算ブレンディングに切り替えて、前面 (または水面) をすべてレンダリングします。上記の式の距離/深度を含むテクスチャが残ります。

ボリュームレンダリング

2 つのアイデアを組み合わせると、マテリアルは透明な固体でありながら、色 (および密度) がボリューム全体で変化します。大量のデータがあり、高速に処理する必要がある場合、これはかなり複雑になります。これをレンダリングする簡単な方法は、3D テクスチャ (または使用している手続き型関数) を介して光線を数値的に積分し、同時に吸収関数を適用することです。基本的な力ずくのオイラー積分では、近くの平面の各ピクセルに対して光線を開始し、均等な距離で前進します。前進する各ステップで、色が一定であると仮定して吸収を適用し、残っている光の量を追跡します。Google で簡単に検索すると、これ

おすすめ記事