1

たとえば、1 つのメッシュに 80 のテクスチャをバインドし、VBO に配置したいと考えています。どうすればこれを達成できますか?

glActiveTexture でそれができることを読みましたが、最大で約 32 のテクスチャを使用できます (GPU に依存)。

私のVBOコード:

//Generating VBO
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vector3d) + textureCoords.size()*sizeof(Vector2d), 0, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size()*sizeof(Vector3d), vertices.data());
glBufferSubData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vector3d), textureCoords.size()*sizeof(Vector2d), textureCoords.data());

glGenBuffers(1, &IND);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IND);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);

//Drawing VBO:
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, VBO);

glVertexPointer(3, GL_DOUBLE, 0, 0);
glTexCoordPointer(2, GL_DOUBLE, 0, (void*)(vertices.size()*sizeof(Vector3d)));

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IND);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void*)0);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4

2 に答える 2

2

多くの (数百の) テクスチャのバインド

一度に多くの個別のテクスチャをバインドする方法がわかりません。バインドレス テクスチャがありますが、その拡張機能についてはあまり経験がありません。多くのテクスチャが同じサイズである場合は、配列テクスチャを使用することもできます。しかし、この問題に対する標準的なアプローチは、テクスチャ アトラスを使用することです。ここでは、多くのテクスチャを 1 つにパックし、それらが配置されている場所を記録し、テクスチャ座標を一致するように調整します。

更新: 多くのテクスチャ配列を使用してテクスチャ アトラスを保存することもできます (コメントと @Ethanの回答を参照)。


複数のテクスチャをメッシュに適用する

どの面がどのテクスチャを持つかを VBO に伝えるにはどうすればよいですか?

差し迫った問題は、同じメッシュに異なるテクスチャ (またはマテリアル) を適用する方法だと思います。考慮すべき点がいくつかあります...

  1. 複数のテクスチャを適用する最も一般的なケースは、それぞれが異なるマテリアル アトリビュートを格納しているが、それらはすべて同じテクスチャ座標/「UV」を使用する場合です。たとえば、拡散マップ、法線マップ、スペキュラ マップ。極端な場合、何百もの異なる属性がある場合は、配列テクスチャが必要になると思います。

  2. 各テクスチャを別々にマッピングする必要がある場合は、テクスチャごとに個別の頂点ごとのテクスチャ座標 VBO が必要です。次に、適用時にテクスチャがどのように相互作用またはブレンドするかを決定する必要があります。

  3. 面ごとに完全に別個のマテリアル/テクスチャがあります。通常、メッシュにはわずかなマテリアルしかありません。レンダリングする方法は、個別のバッチで、マテリアルごとにグループ化されます。適切なテクスチャをバインドし、シェーダー ユニフォームを設定し、三角形のインデックス A から B を描画します。

  4. ほぼすべての面のマテリアルが異なる場合。これは、さまざまなタイルがたくさんあるタイル ベースのゲームを描いている場合に当てはまると思います。ここでの問題は、ドロー コールの数がボトルネックになることです。そのため、異なるマテリアルを同じドロー コールに組み合わせる必要があります。これを行うには、頂点カラー VBO を追加するなど、頂点属性にマテリアルを保存します。色だけでなく、頂点ごとのテクスチャ ID を格納できます。また、テクスチャ アトラスを使用している場合は、アトラス内でテクスチャが見つかる領域を格納できます。三角形の各頂点に同じマテリアル データが複数回保存されるため、これは非効率的になり始めます。オーバーヘッドを最小限に抑えるために、頂点ごとにマテリアル インデックスを格納できます。、どこかのテーブルで定義されたマテリアルを指します (小さな一様配列、またはさらにマテリアルが必要な場合は別のテクスチャ)。次に、テーブル内のマテリアルにテクスチャ ID とアトラス リージョンを追加します。

    うまくいけば、この最後のポイントがあなたの質問に答えます。

于 2015-05-26T14:03:15.273 に答える