1. ホーム
  2. opengl

[解決済み] 最新のOpenGLで複数のテクスチャをレンダリングするには?

2022-02-19 15:32:22

質問事項

現在、小さなゲーム用の2Dエンジンを書いています。

アイデアとしては、1回の描画呼び出しでシーン全体をレンダリングできるようにすることでした。すべての2D画像を4分割してレンダリングすることで、インスタンス化を実現できると考えたのです。

バーテックスシェーダーは次のようなものを想像していました。

...
in vec2 pos;
in mat3 model;
in sampler2d tex;
in vec2 uv;
...

VBOでやるようにgpuでテクスチャを読み込んでハンドルを取ればいいと思ったのですが、そう簡単ではないようです。

を呼び出す必要があるようです。

glActiveTexture(GL_TEXTURE0..N);

を読み込ませたいテクスチャごとに設定します。さて、これは私が考えていたほど簡単なプログラムではないようです。最近のゲームエンジンは、複数のテクスチャをどのようにレンダリングしているのでしょうか?

のテクスチャーの上限が、1,000枚を超えるという記事を読みました。 GL_TEXTURE はGPUに依存しますが、最低でも45です。45枚以上のテクスチャで構成される画像、例えば90枚をレンダリングしたい場合はどうすればいいのでしょうか?

最初の45枚のテクスチャをレンダリングして、gpuからすべてのテクスチャを削除し、残りの45枚のテクスチャをHDDからgpuに読み込まなければならないようです。これは、毎フレーム行うにはあまり合理的とは思えません。特に、2D画像をアニメーションさせたい場合はそうです。

2Dキャラクターの簡単なアニメーションは、10種類の画像で構成されることが容易に想像できます。そうすると、テクスチャーの制限を簡単にオーバーしてしまうことになります。

私の小さなアイデアとしては、複数の画像を1つのメガ画像にまとめ、uv座標でオフセットすることでした。

OpenGLのテクスチャの仕組みを勘違いしていただけなのでしょうか。

OpenGLで複数のテクスチャをレンダリングするにはどうすればいいのでしょうか?

どのように解決するのですか?

質問はやや幅広いので、ここでは、同じ描画呼び出しで複数のテクスチャを使用するためのいくつかのオプションの概要を説明します。

複数のテクスチャユニットにバインドする

この方法では、典型的なシーケンスを使用して、各テクスチャを異なるテクスチャユニットにバインドします。

glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, tex[i]);

シェーダー内では、たくさんの別々の sampler2D ユニフォームの配列、または sampler2D のユニフォームを使用します。

この場合の主な欠点は、利用可能なテクスチャユニットの数に制限があることです。

配列テクスチャ

アレイテクスチャを使用することができます。これを行うには GL_TEXTURE_2D_ARRAY テクスチャターゲット 多くの点で、2Dテクスチャアレイは3Dテクスチャに似ています。基本的には、2Dテクスチャの束を互いに重ねて、1つのテクスチャオブジェクトに保存しています。

欠点は、すべてのテクスチャが同じサイズである必要があることです。そうでない場合は、テクスチャ配列のサイズとして最大のサイズを使用する必要があり、小さなテクスチャのためにメモリを浪費することになります。また、サイズがすべて同じでない場合は、テクスチャの座標にスケーリングを適用する必要があります。

テクスチャアトラス

これは、すでに提示されているアイデアですね。すべてのテクスチャを1つの大きなテクスチャに格納し、テクスチャ座標を使ってどのテクスチャを使用するかを制御します。

一般的な方法ですが、これには技術的な課題もあります。リニアサンプリングでは、テクスチャ同士がにじまないように、テクスチャ同士の継ぎ目に注意する必要があります。また、この方法は、テクスチャ配列とは異なり、メモリを浪費することなくさまざまなテクスチャサイズを使用できますが、アトラス内の領域を割り当てるには、サイズが変わると少し厄介になります。

バインドレステクスチャ

今のところ拡張機能としてのみ利用可能です。 ARB_bindless_texture .