たくさんの木を描くための最良の方法は何ですか


8

木が植えられたランダムな島をレンダリングするアプリを書いています。木は現在2つのクワッドであり、十字で交差し、テクスチャで描かれています。ヤシの木、オーク、草など、さまざまな種類の植物を形成するより複雑なメッシュを使用する予定です。

サンプルアイランド

私が直面する問題は、テクスチャが透明であるため、後ろから前に描画する必要があるということです。Plan-bは、fragシェーダーで破棄を使用することを呼び出しますが、zオーダーの方がより良い結果を提供します。

uniform float uTreeAlpha;
uniform sampler2D uTexture;

varying vec2 vTexCoordOut;

void main (void)
{
  vec4 colour = texture2D(uTexture, vTexCoordOut);
  if (colour.a < 0.1) {
    discard;
  }
  gl_FragColor = vec4(colour.rgb, colour.a * uTreeAlpha);   
}

2番目の問題は、カメラとルックアットによって順序が変わるためです。OpenGLで1回の呼び出しでそれらを描画する効率的な方法がわかりません。

現在、私のレンダリングコードは次の疑似コードのように見えます。

if cameraChangedFromLastTime() then
  sortTreesBackToFront();
end
for i = 0 to trees.size() -1
  drawTree()
end

すべてのdrawTree()がいくつかのユニフォームを設定し、テクスチャを設定してから、glDrawArrays()を呼び出します。最後のツリーと現在のツリーが同じである場合、テクスチャの設定またはテクスチャ座標の更新をスキップするための最適化がいくつかあり、ループの外側にいくつかの一般的なユニフォームを設定します。ループを3000回移動します。

各ツリーを個別に描画すると、パフォーマンスが大幅に低下します。単一の呼び出しまたはバッチ(Zオーダーを維持しながら)でそれらを描画できれば、おそらく1/10の時間でそうなるでしょう。

では、どうすればよいでしょうか。私のツリーはプレースホルダーであり、最終的には次のようになることに注意してください。

  • 異なる木のための異なるメッシュ
  • いくつかのより多様性を与えるために、木の異なるスケールと角度
  • 異なるツリーの異なるテクスチャー、メッシュに適用される可能性のある複数のテクスチャー(例えば、1つのテクスチャーを残し、別のテクスチャーをトランクする)
  • 木はすべて一緒に混合されているため、ある種類を次に別の種類を描画する簡単な方法はありません
  • 何らかの形の単純な循環アニメーション(枝が風に揺れる)
  • すべてのテクスチャは単一のアトラスに存在します

では、ここでの最善のアプローチは何ですか?シングルパスでレンダリングすることは可能ですか?glDrawElementsを使用して、頂点ではなくインデックスを再構築した場合、これを達成できますか?


vterrain.org、植物の下のセクションの植物の下の右側の列、それぞれの左側の列、詳細レベルのレンダリング/一般的なレンダリングの高速化を参照してください。しかし注意してください:ソースはチュートリアルよりも研究論文のより多くのリストです。
Exilyth 2013年

私はこのことについてあまり知りません。しかし、VUEソフトウェアをチェックしてください。3Dで、木、山、大気などのある風景を作成するために使用されます。しかし、それがあなたの状況で役立つかどうかは
わかり

回答:


3

必要なのはハードウェアのインスタンス化です。注:これはXNA(つまりDirectX)で行いましたが、OpenGLについてはあまり知りません。ただし、同等の機能があることは確かです。基本的には、ツリーモデルの頂点を、各インスタンスの世界座標を運ぶ別の頂点ストリームにバインドすることです。


1
OpenGLで同等のものは、拡張機能opengl.org/registry/specs/EXT/draw_instanced.txtになります。ただし、まず、レガシーOpenGLでリストを表示し、最新のOpenGLで頂点配列オブジェクト/頂点バッファーオブジェクトで表示できます。どちらの場合も、オブジェクト/メッシュはリスト/ VAO / VBOに格納され、各インスタンスは異なる変換で描画されます。静的メッシュを使用すると、データを一度アップロードしてから再利用できます。sol.gfxile.net/instancing.htmlは、さまざまな方法の簡単な概要を示しています。
Exilyth 2013年

ありがとう、インスタンス化は興味深いアイデアです。OpenGL ES 2.0を使用していて、すべてに機能するsomethignに取り組んでいるため、draw_instanced拡張を使用できませんでした。おそらく、さまざまなツリーメッシュをVBO(より単純なモデルではさらに遠い可能性があります)、z-sortにロードし、各バッチ用に構築するインデックスバッファーからバッチでそれらを描画できると考えています。そのように一度に30または40を描くことができるかもしれません。
ロッカ2013年

2

透明度は、非加算ブレンドを使用する場合にのみ順序付けする必要があります。大量の遠方の看板の場合、ブレンドは不要です(実際には見えません)。少なくともカットアウトの透明度(アルファが1または0のみ)でさらにレンダリングし、それらを並べ替える必要はありません。

一種のスプライトシートを使用して、ベイクアニメーションでさまざまなタイプの木をレンダリングできます。風や必要なものに基づいて、より忠実にアニメートできる、より近くの木のメッシュを描画します。


破棄を使用してソートを行わないで実験しましたが、結果は少しダフに見えます-木は多く重なり合う傾向があるため、一貫した順序がない場合、1つのツリーが他のツリーの前に来るというポップがたくさん発生し、「ピクセルを獲得します。衝突はまだ時々発生するため(たとえば、カメラから正確に同じ距離にある2つのツリーなど)、破棄を残しましたが、これはフォールバックです。私は看板も実験しましたが、その効果は特に高架道路ではあまりにも偽物です。
ロッカ2013年

より良い看板を使用してください。理想的には、ツリーモデルを使用します。表示角度のビルボードスプライトを生成し、角度がほぼ一致する場所でそのスプライトを使用します。カットアウトの場合、違いがわからない距離で最も効果的に機能します。近づくにつれて、より多くの複製されたモデルを使用する必要があります(おそらくツリーごとに数個のクワッド)、またはスクリーンドアの透明度に切り替えることができます。
Sean Middleditch 2013年

ある時点で、品質と速度の許容範囲を把握する必要があります。一般的なハードウェアのほとんどの複雑なシーンでは、「非常に高速」で「完璧」になることはありません。
Sean Middleditch 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.