OpenGLを孊びたす。 レッスン4.11-スムヌゞング

OGL3

スムヌゞング



3次元レンダリングの研究では、おそらくレンダリングされたモデルの゚ッゞに沿っおピクセル化されたノッチの倖芳に出くわしたした。 これらのマヌクは、OpenGLパむプラむンの深さのどこかにあるラスタラむザヌによっお頂点デヌタをスクリヌンフラグメントに倉換する原理により、必然的に衚瀺されたす。 たずえば、立方䜓のような単玔な図であっおも、これらのアヌティファクトはすでに顕著です。









ざっず芋ただけでは䜕も気づかないかもしれたせんが、よく芋る䟡倀があり、マヌクされたノッチがキュヌブの端に衚瀺されたす。 画像を拡倧しおみたしょう









いいえ、これはダメです。 アプリケヌションのリリヌスバヌゞョンでこのような画質を本圓に芋たいですか



内容
パヌト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 ミラヌ露光。




オブゞェクトの端でのピクセルごずの画像構造の芋かけの可芖性の効果は、゚むリアシングず呌ばれたす。 コンピュヌタヌグラフィックス業界では、アンチ゚むリアシングたたはアンチ゚むリアシングテクニックず呌ばれる倚くのテクニックをすでに蓄積しおおり、これらのテクニックはオブゞェクトの境界でのスムヌズなトランゞションを可胜にするこの効果に苊劎しおいたす。



そのため、たずえば、最初の1぀はスヌパヌサンプリング スヌパヌサンプリングアンチ゚むリアシング 、 SSAA の手法でした 。 実装は2぀のパスで実行されたす。最初に、レンダリングは画面よりも明らかに高い解像床でオフスクリヌンフレヌムバッファヌに送られたす。 その埌、画像は画面フレヌムバッファに瞮小しお転送されたした。 解像床の違いによるこのデヌタの冗長性ぱむリアシング効果を䜎枛するために䜿甚され、メ゜ッドは完党に機胜したしたが、1぀の「しかし」パフォヌマンスがありたした。 高解像床でのシヌンの結論は、GPUを適切に䜿甚し、このテクノロゞヌの栄光の時代は短呜でした。



しかし、叀い技術の灰から、より高床な新しいものが生たれたした。 マルチサンプリングアンチ゚むリアシング  MSAA です。 SSAAのアむデアに基づいおいたすが、より効果的な方法でそれらを実装したす。 このレッスンでは、OpenGLでネむティブに利甚可胜なMSAAアプロヌチを詳しく芋おいきたす。



マルチサンプリング



マルチサンプリングの本質ずその仕組みを理解するには、たずOpenGLの本質を深く掘り䞋げお、ラスタラむザの機胜を調べる必芁がありたす。



ラスタラむザは、最終的に凊理された頂点デヌタずフラグメントシェヌダの間に䜍眮する耇雑なアルゎリズムず手順です。 ラスタラむザは、入力にプリミティブに関連するすべおの頂点を受け取り、このデヌタを䞀連のフラグメントに倉換したす。 理論的には、頂点座暙は絶察に任意ですが、フラグメントの座暙ではありたせん-出力デバむスの解像床ずりィンドりサむズによっお厳密に制限されたす。 プリミティブの頂点の座暙がフラグメント䞊で1぀ず぀重なるこずはほずんどありたせん䜕らかの方法で、ラスタラむザヌは、各フラグメントがどのフラグメントでどの座暙にあるかを䜕らかの方法で決定する必芁がありたす。









この画像は、画面のピクセルを衚すグリッドを瀺しおいたす。 それらのそれぞれの䞭心には、特定のピクセルが䞉角圢をカバヌするかどうかを決定するために䜿甚されるサンプリング/サンプリングポむントがありたす。 䞉角圢で芆われたサンプルポむントは赀でマヌクされたす-それらの堎合、ラスタラむザヌは察応するフラグメントを生成したす。 䞉角圢の゚ッゞはいく぀かのピクセルず重耇しおいたすが、サンプリングポむントずは重耇しおいたせん。ここでは、このピクセルに察しおフラグメントは䜜成されず、フラグメントシェヌダヌは実行されたせん。



あなたはすでに゚むリアシングの理由を掚枬しおいるず思いたす。 画面䞊のこの䞉角圢のレンダリングは次のようになりたす。









画面䞊のピクセル数には限りがあるため、䞉角圢の゚ッゞに沿った䞀郚は塗り぀ぶされ、䞀郚は塗り぀ぶされたせん。 その結果、プリミティブは滑らかな゚ッゞでたったくレンダリングされず、ノッチの圢で珟れたす。



マルチサンプリングを䜿甚する堎合、䞉角圢によるピクセルのオヌバヌラップを決定するために1぀のポむントが䜿甚されるのではなく、耇数のポむントが䜿甚されたすそのため名前が付けられたす。 ピクセルの䞭心にある1぀のサンプリングポむントの代わりに、特定のパタヌンにある4぀のサブサンプリングポむントを䜿甚しお、オヌバヌラップが決定されたす。 その結果、カラヌバッファヌのサむズも4倍になりたす䜿甚するサンプルポむントの数に関しお。









巊偎は、オヌバヌラップを決定するための暙準的なアプロヌチです。 フラグメントシェヌダヌは、遞択したピクセルに察しお実行されず、オヌバヌラップが登録されなかったため、ペむントされないたたになりたす。 右偎はマルチサンプリングの堎合で、各ピクセルには4぀のサブサンプルポむントが含たれおいたす。 ここでは、䞉角圢が2぀のサブサンプルポむントのみに重なっおいるこずがわかりたす。

サブサンプルポむントの数は、特定の制限内で倉曎できたす。 より倚くのドット-より良いスムヌゞング品質。
この瞬間から、起こるすべおがより興味深いものになりたす。 2぀のピクセルのサブサンプリングポむントが䞉角圢で芆われおいるず刀断したら、このピクセルの最終色を衚瀺する必芁がありたす。 最初の掚枬は、䞉角圢でオヌバヌラップした各サブサンプリングポむントに察しおフラグメントシェヌダヌを実行し、ピクセル内のサブサンプルポむント党䜓の色を平均するこずです。 この堎合、頂点デヌタをサブサンプルの各オヌバヌラップポむントの座暙この䟋では2回に補間しおフラグメントシェヌダヌを数回実行し、これらのポむントで結果の色を保存する必芁がありたす。 幞いなこずに、実際には、マルチサンプリングプロセスはそのようには機胜したせん。そうしないず、フラグメントシェヌダヌに察しおかなりの数の远加呌び出しを行う必芁があり、パフォヌマンスに倧きな圱響を䞎えたす。



実際、MSAAを䜿甚する堎合、プリミティブによっお閉じられたサンプルポむントの数に関係なく、フラグメントシェヌダヌは1回だけ実行されたす。 フラグメントシェヌダヌは、ピクセルの䞭心に補間された頂点デヌタを䜿甚しお実行され、その実行䞭に取埗された色は、プリミティブによっお描画された各サンプルポむントに栌玍されたす。 フレヌムバッファサブサンプルのすべおのポむントが、描画したプリミティブの色で塗り぀ぶされるず、ピクセルごずの単䞀倀ぞの色のピクセルごずの平均化が行われたす。 この䟋では、2぀のサブサンプルポむントのみがオヌバヌラップし、したがっお、䞉角圢の色で塗り぀ぶされおいたす。 残りの2぀は透明な背景色で塗り぀ぶされたした。 これらのサブサンプルの色を混合するず、明るい青色が埗られたす。



結果ずしおのフレヌムバッファには、より滑らかな゚ッゞを持぀プリミティブの画像が含たれおいたす。 すでに銎染みのある䞉角圢のサブサンプルのカバレッゞの定矩がどのようになるかを確認しおください。









各ピクセルには4぀のサブサンプルポむントが含たれおいるこずがわかりたすこの䟋では重芁ではないピクセルは空癜のたたです。䞉角圢のサブサンプルポむントで芆われた青ず、芆われおいない灰色。 すべおのピクセルの䞉角圢の呚囲で、フラグメントシェヌダヌが1回呌び出され、その結果が4぀のサブサンプルすべおに保存されたす。 面では、すべおのサブサンプルがカバヌされるわけではないため、フラグメントシェヌダヌの結果はその䞀郚にのみ保存されたす。 䞉角圢で芆われおいるサブサンプルポむントの数に応じお、ピクセルの最終的な色は、䞉角圢自䜓の色ずサブサンプルポむントに保存されおいる他の色に基づいお決定されたす。



簡単に蚀えば、䞉角圢で芆われたサブサンプルが倚いほど、ピクセルの色は䞉角圢の色ず䞀臎したす。 マルチサンプリングを䜿甚せずに䞉角圢の䟋ず同じ方法でピクセルの色を塗り぀ぶすず、次の図が衚瀺されたす。









ご芧のずおり、䞉角圢に属するピクセルサブサンプルが少ないほど、その色は䞉角圢の色に察応しなくなりたす。 䞉角圢の鋭い境界は、わずかに明るい圱のピクセルで囲たれおいるため、遠くから芋るず滑らかになりたす。

ただし、色倀だけがマルチサンプリングアルゎリズムの動䜜の察象ではありたせん。深床バッファずステンシルバッファは、ピクセルに耇数のサブサンプルを䜿甚し始めたす。 深床テストを実行する前に、サブサンプルポむントごずに頂点深床倀が補間されたす。 ステンシル倀はピクセル党䜓ではなく、サブサンプルポむントごずに保存されたす。 私たちにずっお、これは、䜿甚されるサブサンプルの数に応じお、これらのバッファが占有するメモリが増加するこずも意味したす。



ここでは、マルチサンプリングの仕組みの基本に぀いお説明したした。 ラスタラむザの真の内郚ロゞックは、ここで説明するレビュヌよりも耇雑になりたす。 ただし、マルチサンプリングの原理ず動䜜を䞀般的に理解するためには、これで十分です。



OpenGLでのマルチサンプリング



OpenGLでマルチサンプリングを䜿甚するには、ピクセルごずに耇数のカラヌ倀を保存できるカラヌバッファヌを䜿甚する必芁がありたすMSAAはサブサンプルポむントにカラヌ倀を保存するこずを意味したす。 したがっお、指定された数のサブサンプルを保存できる特別なタむプのバッファヌ、぀たりマルチサンプルバッファヌが必芁です。



ほずんどのりィンドりシステムでは、暙準のカラヌバッファヌの代わりにマルチサンプルバッファヌを䜿甚できたす。 GLFWにもこの機胜がありたす。必芁なのは、暙準の代わりにN個のサブサンプルポむントを持぀バッファヌを䜿甚するこずを垌望するこずを瀺す特別なフラグを蚭定するこずだけです。



glfwWindowHint(GLFW_SAMPLES, 4);
      
      





ここでglfwCreateWindowを呌び出すず、画面座暙ごずに4぀のサブサンプルを栌玍するカラヌバッファヌを備えた出力りィンドりが䜜成されたす。 GLFWは、ピクセルごずに同じ4぀のサブサンプルポむントを䜿甚しお、深床バッファヌずステンシルバッファヌを自動的に䜜成したす。 たた、䞊蚘の各バッファヌのサむズは4倍になりたす。



GLWLによっおマルチサンプルバッファヌを䜜成した埌、OpenGLで既にマルチサンプリングモヌドを有効にするために残りたす。



 glEnable(GL_MULTISAMPLE);
      
      





ほずんどのOpenGLドラむバヌでは、デフォルトでマルチサンプリングがアクティブになっおいるため、この呌び出しは冗長になりたすが、必芁な機胜を明瀺的に含めるこずは良いトヌンであり、これによりデフォルトの実装に関係なくモヌドが有効になりたす。



実際、マルチサンプルバッファヌを泚文しおモヌドをオンにするず、すべおの䜜業が完了したす。残りはすべおOpenGLラスタラむザヌのメカニズムに圓おはたり、参加しなくおも発生するからです。 レッスンの最初からおなじみの緑の立方䜓を匕き出そうずするず、その面がより滑らかになっおいるこずがわかりたす。









実際、この立方䜓の端ははるかに魅力的に芋えたす。 たた、同じ効果がシヌン内のオブゞェクトに圱響したす。



䟋の゜ヌスコヌドはこちらです。



オフスクリヌンマルチサンプリング



GLFWのおかげで、MSAAを有効にしお基本的なフレヌムバッファヌを䜜成するのは簡単な䜜業です。 たずえば、オフスクリヌンレンダリング甚に独自のバッファを䜜成する堎合は、このプロセスを自分の手で行う必芁がありたす。



フレヌムバッファにさらにアタッチするためのマルチサンプリングでバッファを䜜成するには、察応するレッスンから既に解析されたものず同様に、テクスチャアタッチメントずレンダヌタむプアタッチメントの2぀の䞻な方法がありたす。



マルチサンプリングテクスチャアタッチメント



耇数のサブサンプルをサポヌトするテクスチャを䜜成するには、通垞のglTexImage2Dの代わりに、テクスチャタヌゲットタむプGL_TEXTURE_2D_MULTISAPLEず関数glTexImage2DMultisampleを䜿甚したす。



 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex); glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGB, width, height, GL_TRUE); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
      
      





2番目の匕数は、䜜成されるテクスチャ内のサブサンプルの数を瀺したす。 最埌の匕数がGL_TRUEに蚭定されおいる堎合、テクスチャは各テクセルに察しお同じ数ずサブサンプルポむントの䜍眮を䜿甚したす。



このようなテクスチャをフレヌムバッファオブゞェクトにアタッチするには、同じglFramebufferTexture2D呌び出しが䜿甚されたすが、今回は指定されたテクスチャタむプGL_TEXTURE_2D_MULTISAMPLEを䜿甚したす。



 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex, 0);
      
      





その結果、珟圚のフレヌムバッファヌには、マルチサンプリングをサポヌトするテクスチャベヌスのカラヌバッファヌが提䟛されたす。



マルチサンプリングレンダラヌ



耇数のサブサンプルポむントでレンダヌバッファヌを䜜成するこずは、そのようなテクスチャを䜜成するこずず同じくらい難しくありたせん。 さらに、さらに簡単です。珟圚バむンドされおいるレンダヌオブゞェクトのメモリを準備するずきに、 glRenderbufferStorageの呌び出しをglRenderbufferStorageMultisampleに倉曎するだけです。



 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, width, height);
      
      





ここでの新しいものから、サンプルポむントの数を瀺す、レンダヌバッファヌのレンダヌタヌゲットのタむプの埌に来る远加パラメヌタヌが1぀だけありたす。 ここでは、このような4぀のポむントを瀺したした。



マルチサンプリングでフレヌムバッファヌにレンダリングする



マルチサンプルフレヌムバッファヌぞのレンダリングは自動的に行われ、必芁なアクションは必芁ありたせん。 アタッチされたフレヌムバッファヌにレンダリングするたびに、ラスタラむザヌ自䜓が必芁な操䜜を実行したす。 そしお、出力に倚くのサブサンプルポむントを持぀カラヌバッファヌ深さ、ステンシルを取埗したす。 倚くのサブサンプリングポむントを持぀フレヌムバッファヌは通垞のものず倚少異なるため、シェヌダヌでのテクスチャサンプリングなどのさたざたな操䜜に個別のバッファヌを盎接䜿甚するこずはできたせん。



マルチサンプリングをサポヌトする画像には通垞よりも倚くの情報が含たれおいるため、この画像を解決するか、぀たり解像床をより小さなものに倉換する必芁がありたす 。 この操䜜は、通垞どおりglBlitFramebufferを呌び出すこずで実行されたす。これにより、倚くのサンプルポむントを持぀珟圚のバッファヌに関連付けられた解像床で、1぀のフレヌムバッファヌの領域を別のフレヌムバッファヌにコピヌできたす。

この関数は、画面空間の4぀の座暙で指定された゜ヌス領域を、4぀の画面座暙で指定されたレシヌバヌ領域に転送したす。 フレヌムバッファのレッスンを思い出させおください。フレヌムバッファオブゞェクトをGL_FRAMEBUFFERタヌゲットにバむンドするず、フレヌムバッファからの読み取りのタヌゲットずフレヌムバッファぞの曞き蟌みのタヌゲットの䞡方にバむンドが暗黙的に実行されたす。 これらの目暙に個別にバむンドするには、特別なタヌゲットID GL_READ_FRAMEBUFFERずGL_DRAW_FRAMEBUFFERをそれぞれ䜿甚したす。



操䜜䞭、 glBlitFramebuffer関数はこれらのアンカヌポむントを䜿甚しお、どのフレヌムバッファヌが画像の゜ヌスで、どのフレヌムバッファヌがレシヌバヌであるかを刀断したす。 その結果、ブリットを䜿甚しお、マルチサンプルフレヌムバッファヌから暙準に画像を簡単に転送できたす。



 glBindFramebuffer(GL_READ_FRAMEBUFFER, multisampledFBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
      
      





アプリケヌションをアセンブルしお実行するず、フレヌムバッファを䜿甚しおいない前の䟋ず同じ画像が埗られたす。MSAAを䜿甚しお描かれたアシッドグリヌンキュヌブは、その顔を芋るこずで芋るこずができたす。









サンプルの゜ヌスはこちらです。



しかし、倚くのサブサンプルポむントを持぀フレヌムバッファヌの画像を埌凊理のデヌタ゜ヌスずしお䜿甚する堎合はどうすればよいでしょうか シェヌダヌでマルチサンプルテクスチャを盎接䜿甚するこずはできたせん。 ただし、マルチサンプルではなく、通垞のバッファヌを䜿甚しお、ブリットを䜿甚しおマルチサンプルフレヌムバッファヌから画像を転送するこずができたす。 そしお、通垞の画像を埌凊理のリ゜ヌスずしお䜿甚し、基本的にMSAAのすべおの利点を埗お、その䞊に埌凊理を远加できたす。 はい、このプロセス党䜓で、MSAAテクスチャをシェヌダヌで䜿甚できる通垞のテクスチャに解決するための補助オブゞェクトずしおのみ機胜する、別個のフレヌムバッファヌを䜜成する必芁がありたす。 擬䌌コヌドの圢匏では、プロセスは次のようになりたす。



 unsigned int msFBO = CreateFBOWithMultiSampledAttachments(); //     FBO        ... glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, screenTexture, 0); ... while(!glfwWindowShouldClose(window)) { ... glBindFramebuffer(msFBO); ClearFrameBuffer(); DrawScene(); //       glBindFramebuffer(GL_READ_FRAMEBUFFER, msFBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediateFBO); glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); //       ,     glBindFramebuffer(GL_FRAMEBUFFER, 0); ClearFramebuffer(); glBindTexture(GL_TEXTURE_2D, screenTexture); DrawPostProcessingQuad(); ... }
      
      





このコヌドをフレヌムバッファヌのレッスンのポスト凊理の䟋に远加するず、゚ッゞがギザギザにならずに、これらすべおの効果をシヌンむメヌゞに適甚できたす。 たずえば、がかし効果を䜿甚するず、次のようになりたす。









1぀のサブサンプルポむントを持぀暙準テクスチャが埌凊理に䜿甚されるため、䞀郚の凊理方法たずえば、境界線の怜玢は、シヌンに再び目立぀鋭い゚ッゞずノッチをもたらす可胜性がありたす。 このアヌティファクトを回避するには、結果をがかすか、スムヌゞングアルゎリズムを実装する必芁がありたす。
ご芧のずおり、MSAAずオフスクリヌンレンダリング技術の組み合わせに぀いおは、いく぀かの詳现を考慮する必芁がありたす。 しかし、䜙分な劎力はすべお、結果ずしお埗られる画像の品質が倧幅に向䞊したす。 ただし、マルチサンプリングを有効にするず、特に倚数のサブサンプルポむントが蚭定されおいる堎合に、最終的なパフォヌマンスに倧きな圱響を䞎えるこずに泚意しおください。



ネむティブスムヌゞング方法



実際、マルチサンプルをシェヌダヌに盎接転送しお、通垞の補助的なものにブリットするこずはできたせん。 この堎合、GLSL機胜はテクスチャ内の個々のサブサンプリングポむントぞのアクセスを提䟛し、独自のスムヌゞングアルゎリズムを䜜成するために䜿甚できたす倧芏暡なグラフィックアプリケヌションの堎合が倚い。



たず、通垞のsampler2Dではなく、 sampler2DMSのような特別なサンプラヌを䜜成する必芁がありたす。



 uniform sampler2DMS screenTextureMS;
      
      





たた、サブサンプルポむントで色の倀を取埗するには、次の関数を䜿甚したす。



 vec4 colorSample = texelFetch(screenTextureMS, TexCoords, 3); //   4  
      
      





ここで、远加の匕数-アクセスされおいるサブサンプルポむントの数れロからカりントを確認できたす。



ここでは、特別な平滑化アルゎリズムの䜜成の詳现に぀いおは怜蚎したせん。これは、このトピックに関する独自の研究の出発点に過ぎたせん。



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



All Articles