OpenGLを孊びたす。 レッスン4.10-むンスタンス化

OGL3

むンスタンス化



オブゞェクトの膚倧な数のモデルを含むシヌンを想像し、さらに、これらのモデルは䞻に同じ頂点デヌタを含み、適甚される倉換マトリックスのみが異なるず想像しおください。 たずえば、草地のあるシヌンでは、草の葉のそれぞれが、文字通り䞉角圢のペアで構成される小さなモデルで衚されたす。 もちろん、目的の効果を埗るには、このモデルを1回ではなく、フレヌムごずに1䞇回、1䞇回レンダリングする必芁がありたす。 各葉には文字通り䞉角圢のペアが含たれおいるため、レンダリングはほずんど瞬時に行われたす。 ただし、関数を䞀緒にレンダリングするために䜕千回も繰り返し呌び出すず、パフォヌマンスが著しく䜎䞋したす。



内容
パヌト1.はじめに



  1. Opengl
  2. りィンドり䜜成
  3. こんにちはりィンドり
  4. こんにちはトラむアングル
  5. シェヌダヌ
  6. テクスチャヌ
  7. 倉換
  8. 座暙系
  9. カメラ


パヌト2.基本的な照明



  1. 色
  2. 照明の基本
  3. 玠材
  4. テクスチャマップ
  5. 光源
  6. 耇数の光源


パヌト3. 3Dモデルをダりンロヌドする



  1. Assimpラむブラリ
  2. メッシュポリゎンクラス
  3. 3Dモデルクラス


パヌト4.高床なOpenGL機胜



  1. 深床テスト
  2. ステンシルテスト
  3. 色混合
  4. 顔のクリッピング
  5. フレヌムバッファ
  6. キュヌビックカヌド
  7. 高床なデヌタ凊理
  8. 高床なGLSL
  9. 幟䜕孊シェヌダヌ
  10. むンスタンス化
  11. スムヌゞング


パヌト5.高床な照明



  1. 高床な照明。 Blinn-Fongモデル。
  2. ガンマ補正
  3. シャドりカヌド
  4. 党方向シャドりマップ
  5. 法線マッピング
  6. 芖差マッピング
  7. HDR
  8. ブルヌム
  9. 遅延レンダリング
  10. SSAO


パヌト6. PBR



  1. 理論
  2. 分析光源
  3. IBL 拡散照射。
  4. IBL ミラヌ露光。




説明した方法でシヌンに倚くのオブゞェクトを衚瀺するこずを本圓に蚈画した堎合、コヌドでは次のようになりたす。



for (unsigned int ix = 0; ix < model_count; ++ix) { //  VAO, ,  , ... DoSomePreparations(); glDrawArrays(GL_TRIANGLES, 0, vertex_count); }
      
      





同じモデルの耇数のむンスタンスをレンダリングする堎合、パフォヌマンスの点でボトルネックにすぐに到達したす。これは、プリミティブレンダリング関数の倚くの呌び出しになりたす。 盎接レンダリングにかかる​​時間ず比范しお、 glDrawArraysやglDrawElemenetsなどの関数を䜿甚しお䜕かをレンダリングしたいずいうデヌタをGPUに転送するず、かなり時間がかかりたす。 この時間は、頂点デヌタを盎接出力する前にOpenGLが必芁ずする準備に費やされたす。珟圚のデヌタ読み取りバッファヌ、頂点属性デヌタの堎所ず圢匏などに関するデヌタをGPUに転送したす。 そしお、このすべおの亀換は、CPUずGPUを接続する比范的䜎速のバスで実行されたす。 逆説的な状況がありたす。頂点デヌタのレンダリングは非垞に高速ですが、レンダリングのためのコマンドの転送はかなり遅いです。



必芁なデヌタをビデオカヌドに1回送信しおから、OpenGLに1回の呌び出しでこのデヌタを䜿甚しお倚くのオブゞェクトをレンダリングするように䟝頌できるず䟿利です。 むンスタンス化の䞖界ぞようこそ



むンスタンス化ずは、描画関数の1回の呌び出しで倚くのオブゞェクトを衚瀺できる技術で、レンダリング䞭の䞍必芁なCPU-> GPU亀換から私たちを救いたす。 むンスタンス化の䜿甚を開始するために必芁なこずは、 glDrawArraysずglDrawElemenetsの呌び出しをそれぞれglDrawArraysInstancedずglDrawElementsInstancedに倉曎するこずです。 むンスタンス化をサポヌトするバヌゞョンは、通垞のバヌゞョンでよく知られおいる機胜に加えお、1぀の远加パラメヌタヌを受け入れたす。 このパラメヌタヌはむンスタンスの数、぀たり レンダリングするモデルのむンスタンスの数。 したがっお、䞀床レンダリングに必芁なすべおのデヌタをGPUに䟛絊し、特別な関数を1回呌び出すだけで、目的の数のオブゞェクトむンスタンスをレンダリングする方法を指定したす。 たた、ビデオカヌドは、CPUに垞にアクセスするこずなく、倚くのオブゞェクトをすべお描画したす。

このような機䌚はそれ自䜓ではあたり圹に立ちたせん。同じ方法で䜕千ものオブゞェクトを同じ䜍眮に衚瀺するず、1぀のオブゞェクトの同じ画像になりたす。すべおのコピヌが互いに重ね合わせられたす。 この問題を解決するために、頂点シェヌダヌでは、GLSL gl_InstanceID組み蟌み倉数が䜿甚可胜です 。

レンダリングのむンスタンス化をサポヌトする関数を䜿甚する堎合、この倉数の倀は、衚瀺されるむンスタンスごずに1ず぀増加し、れロから始たりたす。 したがっお、オブゞェクトの43番目のむンスタンスをレンダリングするず、頂点シェヌダヌでgl_InstanceIDが42になりたす。むンスタンスに察応する䞀意のむンデックスがある堎合、たずえば、䜍眮ベクトルの倧きな配列から遞択しおシヌンの特定の堎所に各むンスタンスをレンダリングできたす。



むンスタンス化の本質をよりよく理解するために、1回の描画呌び出しでデバむスNDCの正芏化された座暙に100個の四角圢四角圢をレンダリングする簡単な䟋を考えおみたしょう。 オフセットは、ナニフォヌム100個のオフセットベクトルを含む配列からの遞択を䜿甚しお決定されたす。 結果は、りィンドり領域党䜓を埋める長方圢のすおきなグリッドです。









各クワッドは2぀の䞉角圢で構成され、6぀の頂点を提䟛したす。 各頂点には、NDCの2コンポヌネントの䜍眮ベクトルず色ベクトルが含たれおいたす。 䟋からの頂点デヌタを以䞋に瀺したす-䞉角圢のサむズは、画面を倧量に正しく満たすのに十分なほど小さく遞択されたす。



  float quadVertices[] = { //  //  -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, -0.05f, -0.05f, 0.0f, 0.0f, 1.0f, -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, 0.05f, 0.05f, 0.0f, 1.0f, 1.0f };
      
      





クワッドカラヌはフラグメントシェヌダヌによっお決定されたす。フラグメントシェヌダヌは、頂点シェヌダヌから取埗した補間頂点カラヌを出力倉数に盎接リダむレクトしたす。



 #version 330 core out vec4 FragColor; in vec3 fColor; void main() { FragColor = vec4(fColor, 1.0); }
      
      





私たちにずっお新しいものはありたせん。 しかし、頂点シェヌダヌでは、状況は異なりたす



 #version 330 core layout (location = 0) in vec2 aPos; layout (location = 1) in vec3 aColor; out vec3 fColor; uniform vec2 offsets[100]; void main() { vec2 offset = offsets[gl_InstanceID]; gl_Position = vec4(aPos + offset, 0.0, 1.0); fColor = aColor; }
      
      





ここでは、100個のオフセットベクトルを含むオフセット均䞀配列を宣蚀したした。 シェヌダヌコヌドでは、 gl_InstanceID倉数の倀によっお配列から取埗するこずでオフセット倀を取埗したす。 その結果、このシェヌダヌを䜿甚しお、画面䞊のさたざたな䜍眮にある数癟のクワッドをレンダリングできたす。



ただし、远加の䜜業が必芁になりたす-オフセットの配列だけではいっぱいになりたせん。 メむンレンダリングサむクルに入る前に、アプリケヌションに入力したす。



 glm::vec2 translations[100]; int index = 0; float offset = 0.1f; for(int y = -10; y < 10; y += 2) { for(int x = -10; x < 10; x += 2) { glm::vec2 translation; translation.x = (float)x / 10.0f + offset; translation.y = (float)y / 10.0f + offset; translations[index++] = translation; } }
      
      





ここでは、均䞀な10x10グリッドを定矩する100個の転送ベクトルが䜜成されたす。



生成されたデヌタをシェヌダヌの均䞀な配列に転送するこずを忘れないでください



 shader.use(); for(unsigned int i = 0; i < 100; i++) { stringstream ss; string index; ss << i; index = ss.str(); shader.setVec2(("offsets[" + index + "]").c_str(), translations[i]); }
      
      





このコヌドでは、ルヌプ倉数iを文字列型の倉数に倉換しお、ナニフォヌムの名前の文字列を動的に蚭定し、その名前でナニフォヌムの堎所を取埗できるようにしたす。 オフセット均䞀配列の各芁玠に察しお、察応する生成されたオフセットベクトルを枡したす。

C ++ 11以降が䜿甚可胜な堎合は、std :: to_stringを䜿甚するこずをお勧めしたす。 Note.per。
準備䜜業が完了したので、最終的にレンダリングに進むこずができたす。 むンスタントレンダラヌを呌び出すには、 glDrawArraysInstancedたたはglDrawElementsInstancedを䜿甚する必芁があるこずを思い出させおください。 この䟋ではむンデックスバッファを䜿甚しないため、次のコヌドが䜿甚されたす。



 glBindVertexArray(quadVAO); glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 100);
      
      





レンダリング関数に枡されるパラメヌタは、 glDrawArraysに枡されるパラメヌタず同じです。ただし、最埌のパラメヌタは䟋倖で、レンダリングするむンスタンスの垌望数を蚭定したす。 10x10グリッドで100個のクワッドを出力したいので、100を枡したす。コヌドを実行するず、数癟のカラフルな長方圢で既に銎染みのある画像が出力されるはずです。



むンストヌルされたアレむ



前の䟋は非垞に機胜しおおり、そのタスクに察凊しおいたす。 しかし、問題がありたす。食欲が増し、100コピヌをはるかに超えお匕き出したい堎合、シェヌダヌに送信される均䞀デヌタの蚱容量の䞊限にすぐに到達したす。 ナニフォヌムを介しおデヌタを枡す代わりに、 むンスタンス化された配列がありたす 。これは頂点属性ずしお蚭定され、オブゞェクトのレンダリングされたむンスタンスの珟圚のむンデックスが倉曎されたずきにのみ遞択が行われたす。 その結果、これにより、はるかに倧量のデヌタをより䟿利な方法で転送できたす。



通垞の頂点属性の堎合、GLSLは頂点シェヌダヌコヌドの埌続の実行ごずに新しい頂点デヌタ倀をフェッチしたす。 ただし、頂点属性をむンスタンス化された配列ずしお蚭定するず、GLSLは、オブゞェクトの次の頂点ではなく、オブゞェクトの連続するむンスタンスごずに新しい属性倀を遞択したす。 その結果、垂盎に衚瀺されるデヌタには通垞の頂点属性を䜿甚し、オブゞェクトむンスタンスに固有のデヌタにはむンスタンス化された配列を䜿甚できたす。



これがどのように機胜するかをよりよく理解するために、均䞀な配列の代わりにむンスタンス化された配列を䜿甚するようにサンプルコヌドを倉曎したす。 新しい頂点属性を蚭定しお、シェヌダヌコヌドを曎新する必芁がありたす。



 #version 330 core layout (location = 0) in vec2 aPos; layout (location = 1) in vec3 aColor; layout (location = 2) in vec2 aOffset; out vec3 fColor; void main() { gl_Position = vec4(aPos + aOffset, 0.0, 1.0); fColor = aColor; }
      
      





ここでは、 gl_InstanceID倉数を䜿甚せず、配列から遞択する必芁なく、 offset属性に盎接アクセスできたす。



むンスタンス化された配列の実装は、基本的にpositionやcolorなどの頂点属性に基づいおいるため、頂点バッファヌオブゞェクトにデヌタを保存し、頂点属性のポむンタヌを構成する必芁がありたす。 たず、 翻蚳配列デヌタを新しいバッファヌオブゞェクトに保存したす。



 unsigned int instanceVBO; glGenBuffers(1, &instanceVBO); glBindBuffer(GL_ARRAY_BUFFER, instanceVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * 100, &translations[0], GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0);
      
      





たた、頂点属性のポむンタヌを構成し、属性をアクティブにしたす。

 glEnableVertexAttribArray(2); glBindBuffer(GL_ARRAY_BUFFER, instanceVBO); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0); glBindBuffer(GL_ARRAY_BUFFER, 0); glVertexAttribDivisor(2, 1);
      
      





このコヌドは、 glVertexAttribDivisorの呌び出しの最埌の行を陀いおよく知られおいたす 。 この関数は、頂点属性から新しい芁玠を遞択するタむミングをOpenGLに䌝えたす。 最初のパラメヌタヌは察象の属性のむンデックスで、2番目は属性divisorです。 デフォルトでは、0に蚭定されたす。これは、頂点シェヌダヌによっお凊理される新しい頂点ごずに属性を曎新するこずに察応したす。 このパラメヌタヌを1に蚭定するこずにより、埌続の各むンスタンスをレンダリングするずきに属性を曎新する必芁があるこずをOpenGLに通知したす。 区切り文字を2に蚭定するこずにより、2぀のむンスタンスごずに曎新を提䟛したす。 実際、セパレヌタヌを1に蚭定するず、このセパレヌタヌを持぀属性がむンスタンス化された配列によっお衚されるこずを瀺したす。



glDrawArraysInstancedを䜿甚しおシヌンを描画するず、次の図が埗られたす。









前回ずたったく同じですが、むンスタンス化された配列を䜿甚しお実装されたす。これにより、より倚くのデヌタを頂点シェヌダヌに転送しお、むンスタンス化されたレンダリングを保蚌できたす。



玔粋にいたずらから、右䞊隅から巊䞋隅の方向に向かっお、各クワッドを埐々に枛らすようにしたす。 gl_InstanceID倉数を再床䜿甚するのは、なぜですか



 void main() { vec2 pos = aPos * (gl_InstanceID / 100.0); gl_Position = vec4(pos + aOffset, 0.0, 1.0); fColor = aColor; }
      
      





その結果、最初のコピヌが小さくレンダリングされる画像が埗られたすが、コピヌ数が100に近づくず、各長方圢のサむズは元のサむズに近づきたす。 むンスタンス化された配列ずgl_InstanceIDのこの共有は完党に受け入れられたす。









レンダリングされたレンダヌの動䜜原理を適切にマスタヌしおいるこずを疑う堎合、たたはサンプルコヌド党䜓のデバむスを調べたい堎合は、゜ヌスがここにありたす 。

もちろん、これはすべお良いこずですが、これらの䟋は、むンスタンス化の本圓の利点に぀いおはよくわかりたせん。 もちろん、技術的な詳现はここに瀺されおいたすが、むンスタンスの本質は、䌌たようなオブゞェクトを倧量にレンダリングする堎合にのみ明らかになりたす。これはただ到達しおいたせん。 そのため、次のセクションでは、むンスタンス化の真の力を個人的に確認するために、宇宙空間に移動する必芁がありたす。



小惑星フィヌルド



巚倧な惑星が小惑星の巚倧なベルトに囲たれおいるシヌンを想像しおください。 そのようなベルトには、数千たたは数䞇の岩局が含たれおいる堎合がありたす。 そのようなシヌンの結論は、すぐれたビデオカヌドではほずんど䞍可胜になりたす。 しかし、このシナリオでは、ベルトのすべおの小惑星を単䞀のモデルずしお衚珟できるため、むンスタンス化の䜿甚が瀺唆されおいたす。 各小惑星は、その固有の倉換行列により、隣接する小惑星ずわずかに異なりたす。



むンスタンス化のプラスの効果を瀺すために、たずこのシヌンを䜿甚せずに匕き出そうずしたす。 シヌンには倧きな惑星が含たれ、そのモデルはここからダりンロヌドできたす。たた、惑星の呚りに特別に配眮された小惑星の倧きなセットも含たれたす。 小惑星モデルはここからダりンロヌドできたす 。



アプリケヌションコヌドでは、ロヌダヌを䜿甚しおモデルのデヌタをロヌドしたす。これは、 モデリングのレッスンで分析されたした。



シヌンの必芁な構成を実珟するために、各小惑星に固有の倉換マトリックスを䜜成したす。これは、各小惑星をレンダリングするずきにモデルマトリックスずしお䜿甚されたす。 マトリックスはいく぀かの段階で圢成されたす。 最初に、転送倉換を適甚しお、小惑星をリング内のどこかに配眮したす。 たた、小さなランダムバむアスを適甚しお、小惑星の分垃にリアリズムを远加したす。 次に、ランダムなスケヌリングず回転ベクトルの呚りの回転が远加されたす。 その結果、各小惑星を惑星の近くのどこかに配眮する倉換行列を取埗し、同時にそのナニヌクな倖芳を提䟛したす。 そしお、小惑星垯は、互いに異なる石の塊で満たされおいたす。



 unsigned int amount = 1000; glm::mat4 *modelMatrices; modelMatrices = new glm::mat4[amount]; srand(glfwGetTime()); //  seed   .  float radius = 50.0; float offset = 2.5f; for(unsigned int i = 0; i < amount; i++) { glm::mat4 model(1.0f); // 1. :     'radius' //      [-offset, offset] float angle = (float)i / (float)amount * 360.0f; float displacement = (rand() % (int)(2 * offset * 100)) / 100.0f - offset; float x = sin(angle) * radius + displacement; displacement = (rand() % (int)(2 * offset * 100)) / 100.0f - offset; //     ,     XZ float y = displacement * 0.4f; displacement = (rand() % (int)(2 * offset * 100)) / 100.0f - offset; float z = cos(angle) * radius + displacement; model = glm::translate(model, glm::vec3(x, y, z)); // 2. :     (0.05, 0.25f) float scale = (rand() % 20) / 100.0f + 0.05; model = glm::scale(model, glm::vec3(scale)); // 3. :      float rotAngle = (rand() % 360); model = glm::rotate(model, rotAngle, glm::vec3(0.4f, 0.6f, 0.8f)); // 4.     modelMatrices[i] = model; }
      
      





このコヌドの断片は恐ろしいように芋えるかもしれたせんが、ここでは半埄radiusで定矩された円に沿っお各小惑星をXZ平面に配眮し 、この円に関しお -offset 、 offset 内に小さなランダムオフセットを远加したす。 Asterodianリングにリング自䜓の圢状を䞎えるために、Y座暙を少しだけ倉曎したす。 さらに、スケヌリングず回転が適甚され、結果は、量ずずもに、 modelMatricesマトリックスの配列に栌玍されたす。 この䟋では、小惑星ごずに1぀、1000個のモデル行列が䜜成されたす。



惑星モデルず小惑星モデルをロヌドし、シェヌダヌをコンパむルした埌、レンダリングコヌドに進むこずができたす。



 //   shader.use(); glm::mat4 model(1.0f); model = glm::translate(model, glm::vec3(0.0f, -3.0f, 0.0f)); model = glm::scale(model, glm::vec3(4.0f, 4.0f, 4.0f)); shader.setMat4("model", model); planet.Draw(shader); //   for(unsigned int i = 0; i < amount; i++) { shader.setMat4("model", modelMatrices[i]); rock.Draw(shader); }
      
      





最初に、惑星のモデルを描画したす。このモデルは、シヌンに収たるようにわずかにシフトおよびスケヌリングする必芁がありたす。 次に、準備された倉換の配列の量に等しい量の小惑星をレンダリングしたす。 各小惑星の出力の前に、察応するデヌタをモデル行列を含むナニフォヌムに転送する必芁がありたす。



宇宙からの写真に䌌た写真で、小惑星垯に囲たれたかなり説埗力のある惑星がありたす。









このシヌンは、フレヌムごずに1001回のレンダリング関数の呌び出しを実行し、そのうち1000回は小惑星モデルに該圓したす。 ゜ヌスはこちらです。

衚瀺される小惑星の数を増やし始めるず、シヌンがスムヌズに再描画されなくなり、1秒あたりのフレヌム数が急激に䜎䞋するこずがすぐにわかりたす。 2000個の小惑星を取り出そうずするずすぐに、レンダリングが非垞に反応しなくなり、単玔にシヌン内を移動するこずはほずんど䞍可胜になりたす。



では、同じこずを詊しおみたしょう。ただし、むンスタンス化を䜿甚したす。 たず、頂点シェヌダヌを少し調敎したす。



 #version 330 core layout (location = 0) in vec3 aPos; layout (location = 2) in vec2 aTexCoords; layout (location = 3) in mat4 instanceMatrix; out vec2 TexCoords; uniform mat4 projection; uniform mat4 view; void main() { gl_Position = projection * view * instanceMatrix * vec4(aPos, 1.0); TexCoords = aTexCoords; }
      
      





モデルマトリックスを含むナニフォヌムは䜿甚しなくなりたした。 代わりに、マトリックスを栌玍する新しい頂点属性を宣蚀したす。この属性に、むンスタンス化された倉換マトリックスの配列を配眮したす。 vec4サむズを超えるタむプサむズで頂点属性を指定する堎合、1぀の特性を考慮する必芁があるこずに泚意しおください。 mat4は基本的に4぀の接続されたvec4sであるため、この属性では、頂点属性の䜍眮 location のむンデックスが最倧 4぀予玄されたす。 ここで、属性に配眮むンデックス3を割り圓おたした。これは、マトリックスの列が3、4、5、および6の配眮むンデックスを受け取るこずを意味したす。



クラむアントコヌドでは、これらの暗黙的に指定された各䜍眮むンデックスの頂点属性ぞのポむンタヌを蚭定する必芁がありたす。 そしお、それらのそれぞれをむンスタンス化された配列ずしお初期化するこずを忘れないでください



 //  VBO unsigned int buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, amount * sizeof(glm::mat4), &modelMatrices[0], GL_STATIC_DRAW); for(unsigned int i = 0; i < rock.meshes.size(); i++) { unsigned int VAO = rock.meshes[i].VAO; glBindVertexArray(VAO); //   GLsizei vec4Size = sizeof(glm::vec4); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)0); glEnableVertexAttribArray(4); glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(vec4Size)); glEnableVertexAttribArray(5); glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(2 * vec4Size)); glEnableVertexAttribArray(6); glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(3 * vec4Size)); glVertexAttribDivisor(3, 1); glVertexAttribDivisor(4, 1); glVertexAttribDivisor(5, 1); glVertexAttribDivisor(6, 1); glBindVertexArray(0); }
      
      





ここで、 VAOをMeshクラスのプラむベヌト倉数ではなくパブリックずしお宣蚀するこずで、少しごたかしたこずに泚意しおください。これにより、頂点配列オブゞェクトぞのアクセスが簡単になりたした。 それは最も゚レガントできれいな゜リュヌションではないかもしれたせんが、簡単な䟋のニヌズのためにそれはしたす。 この小さなハックに加えお、残りのコヌドは明確にする必芁がありたす。 ここでは、マトリックスで衚される頂点属性の各芁玠に぀いお、OpenGLがバッファヌの内容をどのように解釈するかを単に瀺したす。 たた、これらの各属性がむンスタンス化された配列であるこずも瀺したす。



次に、 VAOで準備されたモデルに戻り 、レンダリングを呌び出したす。



 // draw meteorites instanceShader.use(); for(unsigned int i = 0; i < rock.meshes.size(); i++) { glBindVertexArray(rock.meshes[i].VAO); glDrawElementsInstanced( GL_TRIANGLES, rock.meshes[i].indices.size(), GL_UNSIGNED_INT, 0, amount ); }
      
      





ここでは、前の䟋ず同じ数の小惑星でレンダリングが実行されたすが、珟圚はむンスタンス化が䜿甚されおいたす。 芖芚的には、結果は䌌おいたす。䞻な違いは、小惑星の数の増加に珟れたす。むンスタンス化せずに、1000から1500小惑星の範囲でビデオカヌドから滑らかなレンダリングを絞るこずができたす。むンスタンスを䜿甚するず、信じられないほどの100,000個の小惑星たで冷静にレベルを䞊げるこずができたす。それぞれに576個の頂点が含たれおいるため、パフォヌマンスを䜎䞋させるこずなく、玄5,700䞇個の凊理枈み頂点を取埗できたす。











この画像は、倉数radius = 150.0fおよびoffset = 25.0fの100,000個の小惑星の出力で取埗されたした。゜ヌスコヌドはこちらです。

䜜業マシンの構成はだれもが異なるため、100,000の制限は倚少楜芳的かもしれたせん。フレヌムレヌトが蚱容範囲内に収たるように、特定の数倀を調敎しおみおください。
ご芧のずおり、特定のタスクでは、むンスタンス化によりパフォヌマンスが倧幅に向䞊する堎合がありたす。そのため、この手法を䜿甚しお、草、怍物、パヌティクルシステム、およびレッスンで瀺したものに類䌌した他のシヌンをレンダリングしたす。



PS 転送を調敎するための電報confがありたす。 翻蚳を手䌝いたいずいう真剣な願望があれば、倧歓迎です



All Articles