[解決済み] 最新のOpenGLで複数のテクスチャをレンダリングするには?
質問事項
現在、小さなゲーム用の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 .
関連
-
[解決済み] X リクエストが失敗したときのエラー。BadValue (整数パラメータが操作の範囲外です)
-
[解決済み] glReadPixelsはどのように動作するのですか?
-
[解決済み] Emscripten/OpenGLのコードで「glDrawArrays: attribute 1の範囲外の頂点にアクセスしようとする」(ネイティブC++では動作する) [終了しました]
-
[解決済み] glBlitFramebufferを使用してテクスチャを表示する
-
[解決済み] 頂点シェーダとフラグメントシェーダにおけるgl_Colorとgl_FrontColorの関係を教えてください。
-
[解決済み] glGetShaderiv() GL_COMPILE_STATUS GL_FALSE を返す
-
[解決済み] OpenGL - GLenumはどのように符号なし32ビット整数ですか?
-
opengl glGetIntegerv エラーを使用します。アクセス違反 ロケーション0x0000000000000000を実行中
-
[解決済み] OpenGL - glDepthMaskの使い方についての質問です。
-
[解決済み] OpenGLのフレームバッファとレンダーバッファの概念と違いについて教えてください。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] X リクエストが失敗したときのエラー。BadValue (整数パラメータが操作の範囲外です)
-
[解決済み] OpenGL - なぜ、インデックスのためのGL_ELEMENT_ARRAY_BUFFERなのですか?
-
[解決済み] Emscripten/OpenGLのコードで「glDrawArrays: attribute 1の範囲外の頂点にアクセスしようとする」(ネイティブC++では動作する) [終了しました]
-
[解決済み] glGetShaderiv() GL_COMPILE_STATUS GL_FALSE を返す
-
[解決済み] OpenGL - GLenumはどのように符号なし32ビット整数ですか?
-
[解決済み] Ken Silverman氏のVoxlapエンジンで使用されているアルゴリズムについて、どなたか教えてください。
-
[解決済み] コンセプト:glDrawBufferとglDrawBuffersの使い分けは?
-
[解決済み] gl_FragColorとout vec4カラーを使用する?
-
[解決済み] OpenGLのフレームバッファとレンダーバッファの概念と違いについて教えてください。
-
[解決済み] glActiveTextureとglBindTextureの違いと関係