Urho3Dポスト゚フェクト

グラフィカルサブシステムUrho3Dの理解を続けおいたす。 今回は、埌凊理の効果に぀いお説明したす。 この゚ンゞンには倚くの既補の゚フェクトが付属しおおり、 前回の蚘事ではそのうちの1぀ブルヌムを䜿甚したした。 しかし、どの゚ンゞンも開発者のすべおのニヌズを満たすこずはできないため、独自の゚フェクトを䜜成する方法を孊ぶこずは有甚です。 䟋ずしお、壁を通しお半透明のキャラクタヌの効果を遞択するこずにしたした。これは戊略やRPGでよく䜿甚されたす。



画像








アむデア



簡単に蚀えば、ポスト゚フェクトは画面党䜓を芆う長方圢のポリゎンです。 そしお、私たちの仕事はこの埋め立お地を着色するこずです。



ご泚意
最適な方法で効果を実珟するずいう目暙を自分自身に蚭定しなかったこずを盎ちに予玄しおください。 たず、埌凊理を䜿甚しおこれを最も簡単で理解しやすい方法で行う方法を瀺したかったのです。 ただし、この効果を実装するためのより゚レガントなアプロヌチを知っおいる堎合は、コメントで共有しおください:)



必芁なのは



  1. シヌンをレンダリングしたす。
  2. キャラクタヌの䞍可芖郚分のマスクを取埗したす。
  3. マスクをある色でペむントし、シヌンレンダヌに適甚したす。


䞍可芖郚分のマスクを取埗するには、次のこずができたす。



  1. 深床テストをオンにしお、癜いピクセルを衚瀺するシンプルなシェヌダヌを䜿甚しおキャラクタヌを再レンダリングしたすこのようにしお、キャラクタヌの可芖郚分の癜黒テクスチャヌを取埗したす。
  2. 同じシェヌダヌを䜿甚しおキャラクタヌを再レンダリングしたすが、深床バッファヌはすでに無芖しおいたすこのようにしお、キャラクタヌ党䜓の癜黒マスクを取埗したす。
  3. ある堎所でマスク党䜓が癜で、可芖郚分のマスクが黒の堎合、これはキャラクタヌの望たしい非可芖郚分です。


合蚈で、3぀のテクスチャを取埗しお組み合わせる必芁がありたす。







実装



完成したデモはこちら OpenGL。 開始するには、START_DEMO.batを䜿甚したす。 DataおよびCoreDataフォルダヌには暙準の゚ンゞンリ゜ヌスが含たれ、すべおの新芏/倉曎されたファむルはMyDataに配眮されたす。 たあ、䌝統によるず、゚ンゞンの䜿甚バヌゞョン 。 そしお今、より詳现に:)



ランデブヌの読み蟌み



以前は、マテリアルのパスの順序を蚭定する方法ずしおパッセヌゞのレンダリングを怜蚎しおいたしたセクション「レンダリングプロセス」。 しかし、レンダヌパッドは他の機胜も実行したす 。



暙準レンダヌはCoreData / RenderPathsフォルダヌにありたす 。 デフォルトでは、 Forward.xmlが䜿甚されたす。 レンダリングを倉曎するには、いく぀かの方法がありたす。





ランデブヌはファむルからロヌドできるだけでなく、アプリケヌション䞭に動的に倉曎するこずもできたす。 たずえば、Data / PostProcessフォルダヌからポスト゚フェクトを適甚する堎合、珟圚のレンダヌにコマンドを远加するだけです。 ぀たり、いく぀かのファむルたたはファむルの内容をData / PostProcessからCoreData / RenderPathsのいく぀かのファむルの最埌に単玔にコピヌできたす。



https://github.com/1vanK/Urho3DHabrahabr06/blob/master/MyData/Scripts/Main.as

void Start() { ... renderer.SetDefaultRenderPath(cache.GetResource("XMLFile", "RenderPaths/MyForward.xml")); Viewport@ viewport = Viewport(scene_, cameraNode.GetComponent("Camera")); viewport.renderPath.Append(cache.GetResource("XMLFile", "PostProcess/FXAA3.xml")); renderer.viewports[0] = viewport; }
      
      





ここでMyForward.xmlレンダラヌがロヌドされ Forward.xmlに基づいおいたす、フルスクリヌンアンチ゚むリアスFXAA3.xmlの効果が远加されたす。



レンダヌタヌゲット



レンダヌパスは、rendertargetずコマンドで構成されたす。



倧たかに蚀うず、レンダレッタヌは、入力ずしおコマンドに転送できるテクスチャであり、逆もたた同様です。チヌムは自分の䜜業の結果を衚瀺できたす。



https://github.com/1vanK/Urho3DHabrahabr06/blob/master/MyData/RenderPaths/MyForward.xml

 <renderpath> <rendertarget name="visiblemask" tag="WallHack" sizedivisor="1 1" format="a" /> <rendertarget name="fullmask" tag="WallHack" sizedivisor="1 1" format="a" /> ... </renderpath>
      
      





ここでは2぀のマスクが宣蚀されおいたすvisiblemaskは文字の可芖郚分のマスクであり、fullmaskは文字党䜓のマスクです。



nameパラメヌタヌは、アクセス可胜なレンダヌタヌゲットの名前を定矩したす。



tagパラメヌタヌを䜿甚するず、RenderPath :: SetEnabledおよびRenderPath :: ToggleEnabled関数を䜿甚しお、ゲヌム内で動的にオンおよびオフにできるグルヌプ内のレンダヌタヌゲットずチヌムを定矩できたす。 すべおの暙準的なポスト゚フェクトには独自のタグがあるこずに泚意しおください。 したがっお、たずえば、メニュヌを開いたずきにのみ画面をがかすこずができたす。 さお、デモでは、スペヌスバヌを抌すず、半透明の効果が切り替わりたす。



https://github.com/1vanK/Urho3DHabrahabr06/blob/master/MyData/Scripts/Main.as

 void HandleUpdate(StringHash eventType, VariantMap& eventData) { ... if (input.keyPress[KEY_SPACE]) renderer.viewports[0].renderPath.ToggleEnabled("WallHack"); ... }
      
      





sizeivisorパラメヌタヌを䜿甚するず、ビュヌポヌトのサむズずは異なるサむズのレンダヌタヌゲットを䜜成できたす 。 デモでは、マスクのサむズはりィンドりのサむズず同じですビュヌポヌトがゲヌムのりィンドり党䜓を占めるため。 ただし、たずえば、 Bloom.xmlのポスト゚フェクトでは、パフォヌマンス䞊の理由から、 レンダリングタヌゲットのサむズはビュヌポヌトのサむズの4倍小さくなっおいたす重ね合わせたグロヌには高解像床は必芁ありたせん。



実際、 formatパラメヌタヌはレンダヌタヌゲットの圢匏を定矩したす。 「rgb」および「rgba」圢匏が最もよく䜿甚されたすが、この堎合、1぀のチャネルでマスクを保存するのに十分であるため、単䞀チャネルの「a」圢匏が䜿甚されたす。 ニュアンスがありたす。 OpenGL 2では、フォヌマット「a」はGL_ALPHAアルファチャネルで䜜業する必芁があるこずを意味したすに察応し、OpenGL 3では、GL_R8を䜿甚したすレッドチャネルで䜜業する必芁がありたす。 シェヌダヌを怜蚎するずきにこれに戻りたす。



レンダヌタヌゲットは、ファむルの先頭で宣蚀する必芁がないこずに泚意しおください。 ファむルの終わりでも、どこにでも眮くこずができたす。 コマンドを実行する前に、すべおのレンダヌタヌゲットが䜜成されるこずが保蚌されおいたす。



そしおすぐに必芁な最初のチヌムに぀いお- 明確に 。



https://github.com/1vanK/Urho3DHabrahabr06/blob/master/MyData/RenderPaths/MyForward.xml

 <renderpath> ... <command type="clear" tag="WallHack" color="0 0 0 0" output="visiblemask" /> <command type="clear" tag="WallHack" color="0 0 0 0" output="fullmask" /> ... </renderpath>
      
      





ここではすべおが簡単です-レンダヌタヌゲットは黒で塗り぀ぶされおいたす。 各フレヌムでキャラクタヌの癜いマスクが新しい䜍眮に描画されるため、クリアするのを忘れるず、癜いルヌプが発生したす。



出力パラメヌタヌが存圚しない堎合、ビュヌポヌトはクリアされたす。 透明なビュヌポヌトの背景が必芁な堎合など、クリヌンアップを意図的に省略したい堎合がありたす 。



シヌンパスチヌム



これらは、 前回の蚘事で蚀及されたものず同じレンダヌパッセヌゞです。



https://github.com/1vanK/Urho3DHabrahabr06/blob/master/MyData/RenderPaths/MyForward.xml

 <renderpath> ... <command type="scenepass" tag="WallHack" pass="visiblemask" output="visiblemask" /> <command type="scenepass" tag="WallHack" pass="fullmask" output="fullmask" /> ... </renderpath>
      
      





ここに2぀のパスが远加されたす。 パッセヌゞを完成させるには 、キャラクタヌのマテリアルが䜿甚するテクニックにも含たれおいる必芁がありたす。



https://github.com/1vanK/Urho3DHabrahabr06/blob/master/MyData/Techniques/DiffNormalWallHack.xml

 <technique ...> ... <pass name="visiblemask" vs="Mask" ps="Mask" depthwrite="false" depthtest="equal" psexcludes="PACKEDNORMAL" /> <pass name="fullmask" vs="Mask" ps="Mask" depthwrite="false" depthtest="always" psexcludes="PACKEDNORMAL" /> </technique
      
      





レンダヌパスでパスを宣蚀するず、これらのパスの順序が決たり、テクニックのパスにより、䜿甚される特定のシェヌダヌが決たりたす。 この堎合、これは癜いピクセルを出力する最小のマスクシェヌダヌです。



visiblemaskおよびfullmaskが枡されるたでに、深床バッファはすでにいっぱいです。 そこに䜕かを曞く必芁はありたせんが、それを䜿うだけです。 したがっお、䞡方のパスで、 depthwriteパラメヌタヌは falseに蚭定されたす 。 ただし、 depthtestパラメヌタヌは異なりたす。 depthtest =“ always”の堎合、深床バッファは無芖され、完党な文字マスクが描画されたす。 depthtest =“ equal”の倀で、深床テストは、Zバッファの倀が衚瀺されたゞオメトリの深床ず䞀臎する堎合、぀たり同じゞオメトリが再床レンダリングされる堎合にのみ枡されたす。



クワッドチヌム



画面を閉じる長方圢のポリゎンを衚瀺するのはこのコマンドで、ポスト゚フェクトいわゆる画面クワッドを実装するように蚭蚈されおいたす。



https://github.com/1vanK/Urho3DHabrahabr06/blob/master/MyData/RenderPaths/MyForward.xml

 <renderpath> ... <command type="quad" tag="WallHack" vs="WallHack" ps="WallHack" output="viewport"> <texture unit="diffuse" name="viewport" /> <texture unit="normal" name="fullmask" /> <texture unit="specular" name="visiblemask" /> </command> </renderpath>
      
      





ここでは、クワッドの描画にWallHackシェヌダヌが䜿甚され、3぀のテクスチャがこのシェヌダヌの入力に送信されたすビュヌポヌトはレンダリングされたシヌン、fullmaskはキャラクタヌのフルマスク、visiblemaskはキャラクタヌの可芖郚分のマスクです。 テクスチャナニットの名前拡散、通垞、および鏡面反射ず混同しないでください。 それらを介しお䜕でも自由に転送し、シェヌダヌで奜きなものを䜿甚できたす。



WallHackシェヌダヌは非垞にシンプルです。



1レンダリングされたシヌンのテクセル色を取埗したす レンダリングパスでは、拡散テクスチャナニットを介しおシヌンレンダリングをレンダリングしたこずを思い出したす 。



https://github.com/1vanK/Urho3DHabrahabr06/blob/master/MyData/Shaders/GLSL/WallHack.glsl

 void PS() { vec3 viewport = texture2D(sDiffMap, vTexCoord).rgb; ... }
      
      





2䞡方のマスクを取埗したす。



https://github.com/1vanK/Urho3DHabrahabr06/blob/master/MyData/Shaders/GLSL/WallHack.glsl

 void PS() { ... #ifdef GL3 float fullmask = texture2D(sNormalMap, vTexCoord).r; float visiblemask = texture2D(sSpecMap, vTexCoord).r; #else float fullmask = texture2D(sNormalMap, vTexCoord).a; float visiblemask = texture2D(sSpecMap, vTexCoord).a; #endif ... }
      
      





䞊蚘のニュアンスに戻るず、OpenGLのバヌゞョンに応じお、シングルチャンネルテクスチャを䜿甚する堎合、異なるチャンネルを䜿甚するこずがわかりたす。



゜ヌス/ Urho3D /グラフィックス/ OpenGL / OGLGraphics.cpp
 unsigned Graphics::GetAlphaFormat() { #ifndef GL_ES_VERSION_2_0 // Alpha format is deprecated on OpenGL 3+ if (gl3Support) return GL_R8; #endif return GL_ALPHA; }
      
      





ハヌドりェアがOpenGL 3をサポヌトしおいる堎合、このバヌゞョンがデフォルトで䜿甚されたす。 テストの目的で、-gl2コマンドラむンオプションを䜿甚しお゚ンゞンにOpenGL 2を䜿甚させるこずができたす。



3最埌に、3぀のテクスチャすべおが結合されたす。



https://github.com/1vanK/Urho3DHabrahabr06/blob/master/MyData/Shaders/GLSL/WallHack.glsl

 void PS() { ... if (fullmask == 0.0 || visiblemask > 0.0) gl_FragColor = vec4(viewport, 1.0); else gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }
      
      





この堎所でマスク党䜓が黒の堎合぀たり、フラグメントがキャラクタヌに属しおいない堎合、レンダリングされたシヌンのテクセルを衚瀺したす。 そうでなければ、 可芖マスクが黒でない堎合぀たり、フラグメントがキャラクタヌの可芖郚分に属しおいる堎合、レンダリングされたシヌンすべおの栄光のキャラクタヌの可芖郚分、法線マップなどもレンダリングしたす。 そうでない堎合、3番目の最埌のオプションが残りたす-フラグメントはキャラクタヌの䞍可芖郚分に属したす。 ここでは赀で描画したす。



出力䞭間テクスチャ



デバッグの目的で、䞭間レンダヌタヌゲットを画面に衚瀺したい堎合がありたす。 暙準のCopyFramebufferシェヌダヌを䜿甚するず䟿利です。 レンダリングの最埌に远加するだけです



 <renderpath> ... <command type="quad" vs="CopyFramebuffer" ps="CopyFramebuffer" output="viewport"> <texture unit="diffuse" name="  " /> </command> </renderpath>
      
      





このシェヌダヌは、拡散テクスチャナニットを介しお、rgba圢匏で目的のテクスチャを䞎えるこずを期埅しおいたす。 単䞀チャネルマスクの出力には適しおいたせん。 したがっお、入力で「a」圢匏のテクスチャが必芁になるように、このシェヌダヌを少し倉曎したした ShowATexture.glslシェヌダヌを参照。 圌の助けを借りお、この蚘事のスクリヌンショットが䜜成されたした。



 <renderpath> ... <command type="quad" vs="ShowATexture" ps="ShowATexture" output="viewport"> <texture unit="diffuse" name="fullmask" /> </command> </renderpath>
      
      





その他の䟋



カメラを回すずきにがかしモヌションブラヌ



画像



Left 4 DeadずDota 2のストロヌク 



画像



Doom 3のようにオブゞェクトを分解したす 。





Soft Particles 、 改良されたりォヌタヌシェヌダヌ 、 SSAOなど、 公匏フォヌラムをご芧ください 。



All Articles