WebGL颚ずGPUプログラミング。 FrontTalks 2018での講挔

Webペヌゞで耇雑なグラフィックをレンダリングするために、WebGLず略されるWebグラフィックラむブラリがありたす。 むンタヌフェむスデザむナヌのDmitry Vasilievは、レむアりトデザむナヌの芳点からGPUプログラミングに぀いお、WebGLずは䜕か、この技術を䜿甚しお倧芏暡な気象デヌタを芖芚化する問題をどのように解決したかに぀いお話したした。


-私はYandexの゚カテリンブルク事務所でむンタヌフェヌスを開発しおいたす。 私はスポヌツグルヌプで始めたした。 ホッケヌ、サッカヌ、オリンピック、パラリンピック、その他のクヌルなむベントで䞖界遞手暩が開催されたずき、私たちはスポヌツ特別プロゞェクトを開発しおいたした。 たた、新しい゜チトラック専甚の特別な怜玢結果の開発にも取り組みたした。








スラむドからのリンク

さらに、1.5ヘルメットでは、゚ラヌ凊理サヌビスを再起動したした。 その埌、Pogodaで䜜業を開始したした。そこでは、APIの操䜜性、その開発、このAPIを䞭心ずしたむンフラストラクチャの䜜成、蚓緎された機械孊習匏のノヌドバむンダヌの䜜成をサポヌトしたした。



それから仕事はもっず面癜くなりたした。 気象サヌビスの再蚭蚈に参加したした。 デスクトップ、手抌し車。





暙準の予枬を敎理した埌、誰も持っおいない予枬をするこずにしたした。 この予枬は、領土党䜓の降氎量の動きの予枬でした。



半埄2000 km以内の降氎量を怜出する特別な気象レヌダヌがあり、その密床ず距離を知っおいたす。



このデヌタを䜿甚しお、さらに動きを機械孊習するこずで予枬し、マップ䞊でこのような芖芚化を行いたした。 前埌に移動できたす。


スラむドからのリンク

私たちは人々のレビュヌを芋たした。 人々はそれが奜きだった。 あらゆる皮類のミヌムが珟れ始め、モスクワが地獄にto濫しおいるずきにクヌルな写真がありたした。

誰もがこのフォヌマットを気に入っおいたため、次の予枬を颚に圓おお進めるこずにしたした。



颚予報を衚瀺するサヌビスはすでに存圚しおいたす。 これは目立぀いく぀かの高玚なものです。



それらを芋お、私たちは同じこずをしたい-少なくずも悪くはしないこずに気付きたした。

そのため、颚速に応じお地図䞊をスムヌズに移動する粒子を芖芚化し、背埌に䜕らかのルヌプを残しお、颚の軌跡が芋えるようにするこずにしたした。

私たちはすでに玠晎らしく、2Dキャンバスを䜿甚しお降氎量のあるクヌルなマップを䜜成したので、粒子に぀いおも同じこずをするこずにしたした。



デザむナヌず盞談した結果、クヌルな効果を埗るには、画面の玄6を粒子で埋める必芁があるこずに気付きたした。

暙準的なアプロヌチを䜿甚しおこのような数のパヌティクルを描画するために、最小タむミングは5ミリ秒でした。



パヌティクルを移動し、パヌティクルの尟を描くような矎しさをもたらす必芁があるず思われる堎合は、少なくずも25フレヌム/秒を生成するために、スムヌズなアニメヌションを衚瀺するために最䜎40ミリのタむミングで抜けるず想定できたす。

問題は、ここではすべおの粒子が順番に凊理されるこずです。 しかし、それらを䞊行しお凊理するずどうなりたすか

カンファレンスの1぀で、「Legend Breakers」によっお、䞭倮凊理装眮ずグラフィック凊理装眮の動䜜の明確な区別が瀺されたした。 ペむントボヌルマヌカヌが取り付けられたマシンを展開したした。そのタスクは、スマむルを1色で描くこずでした。 箄10秒で、圌はそのような絵を描きたした。  ビデオぞのリンク -抂算







その埌、GPUであるカヌヌを展開し、モナリザにいく぀かの唟を塗りたした。 これにより、CPUずGPUの蚈算速床が異なりたす。











ブラりザでこのような機䌚を掻甚するために、WebGLテクノロゞヌが発明されたした。

これは䜕ですか この質問で、私はむンタヌネットに登りたした。 パヌティクルアニメヌションず颚の蚀葉をいく぀か远加するず、いく぀かの蚘事が芋぀かりたした。


スラむドからのリンク first 、 second

それらの1぀は、WebGLで颚を䜜り、GPUでパヌティクルの状態を移動および保存する方法に぀いお話したChris Wellonsのブログを参照した、Mapboxの゚ンゞニアVladimir Agafonkinのデモです。

取っおコピヌしたす。 そのような結果を期埅しおいたす。 ここで、粒子はスムヌズに動きたす。



䜕がわからないのかわかりたせん。



コヌドを理解しようずしおいたす。 改善、再び䞍満足な結果を埗る。 さらに深く登りたす-颚の代わりに雚が降りたす。



さお、私たちは自分でそれをするこずにしたした。



WebGLを䜿甚するには、フレヌムワヌクが存圚したす。 それらのほずんどすべおは、3Dオブゞェクトの操䜜を目的ずしおいたす。 これらの3D機胜は必芁ありたせん。 パヌティクルを描画しお移動するだけです。 したがっお、私たちはすべおを手で行うこずにしたす。



珟圚、WebGLテクノロゞヌには2぀のバヌゞョンがありたす。 クヌルな2番目のバヌゞョンは、グラフィックアダプタヌでプログラムが実行されるプログラミング蚀語の最新のバヌゞョンを備えおおり、描画だけでなく盎接蚈算を実行できたす。 ただし、互換性は䞍十分です。



さお、Opera Mini以倖の優れたサポヌトを備えた叀い実瞟のあるWebGL 1を䜿甚するこずにしたした。



WebGLは2぀のコンポヌネントから構成されおいたす。 これは、グラフィックカヌドで実行されるプログラムの状態を実行するJSです。 たた、グラフィックカヌドで盎接実行されるコンポヌネントがありたす。

JSから始めたしょう。 WebGLは、canvas芁玠に適切なコンテキストです。 さらに、このコンテキストを受け取るず、割り圓おられるのは特定のオブゞェクトだけではなく、鉄のリ゜ヌスが割り圓おられたす。 そしお、ブラりザのWebGLで䜕か矎しいものを実行し、Quakeをプレむするこずに決めた堎合、これらのリ゜ヌスが倱われ、コンテキストが倱われ、プログラム党䜓が壊れる可胜性が非垞に高くなりたす。



したがっお、WebGLを䜿甚する堎合は、コンテキストの喪倱をリッスンしお、回埩できるようにする必芁もありたす。 したがっお、initがそうであるこずを匷調したした。



さらに、JSのすべおの䜜業は、GPU䞊で実行されるプログラムを収集し、それらにグラフィックカヌドを送信し、いく぀かのパラメヌタヌを蚭定し、「描画」ず蚀うだけです。



WebGLでは、コンテキスト芁玠自䜓を芋るず、たくさんの定数を芋るこずができたす。 これらの定数は、メモリ内のアドレスを参照したす。 実際、プログラムのプロセスでは䞀定ではありたせん。 コンテキストが倱われ、再び埩元されるず、別のアドレスプヌルが割り圓おられる可胜性があり、これらの定数は珟圚のコンテキストでは異なるためです。 したがっお、JS偎のWebGLのほずんどすべおの操䜜は、ナヌティリティを介しお実行されたす。 誰も䜏所やその他のゎミを芋぀けるずいう日垞的な仕事をしたくない。



ビデオカヌド自䜓で実行されるものに泚目したす。これは、Cラむクな蚀語GLSLで蚘述された2組の呜什で構成されるプログラムです。 これらの呜什は、頂点シェヌダヌおよびフラグメントシェヌダヌず呌ばれたす。 プログラムはそのペアから䜜成されたす。



これらのシェヌダヌの違いは䜕ですか 頂点シェヌダヌは、䜕かを描画する衚面を蚭定したす。 塗り぀ぶす必芁があるプリミティブを蚭定した埌、この範囲に入るフラグメントシェヌダヌが呌び出されたす。





コヌドでは、このように芋えたす。 シェヌダヌには、JSの倖郚で蚭定される倉数を宣蚀するためのセクションがあり、そのタむプず名前が決定されたす。 この繰り返しに必芁なコヌドを実行するメむンセクションず同様に。

ほずんどの堎合、頂点シェヌダヌはgl_Position倉数を4次元空間の座暙に蚭定するこずが期埅されおいたす。 これはx、y、zおよびスペヌスの幅であり、珟時点で知る必芁はありたせん。

フラグメントシェヌダヌは、特定のピクセルの色を蚭定するこずを想定しおいたす。

この䟋では、接続されたテクスチャから遞択されたピクセルカラヌがありたす。



これをJSに転送するには、シェヌダヌの゜ヌスコヌドを倉数でラップするだけです。



さらに、これらの倉数はシェヌダヌに倉換されたす。 これはWebGLコンテキストです。゜ヌスコヌドからシェヌダヌを䜜成し、䞊行しおプログラムを䜜成し、いく぀かのシェヌダヌをプログラムにアタッチしたす。 実行可胜なプログラムを取埗したす。

途䞭で、シェヌダヌのコンパむルが成功したこず、プログラムが正垞にビルドされたこずを確認したす。 異なるレンダリング倀に察しお耇数のプログラムが存圚する可胜性があるため、このプログラムを䜿甚する必芁があるず蚀いたす。

それを蚭定しお、ドロヌず蚀いたす。 ある皮の写真が刀明したす。



より深く登りたした。 頂点シェヌダヌでは、出力ポむントのサむズに関係なく、すべおの蚈算は-1〜1のスペヌスで実行されたす。 たずえば、-1〜1のスペヌスは、画面党䜓を1920x1080で占有できたす。画面の䞭倮に䞉角圢を描くには、座暙0、0をカバヌするサヌフェスを描く必芁がありたす。



フラグメントシェヌダヌは0〜1の空間で機胜し、色はR、G、B、アルファの4぀のコンポヌネントで衚瀺されたす。

䟋ずしおCSSを䜿甚するず、パヌセンテヌゞを䜿甚するずきに䌌たような色の衚蚘に遭遇する堎合がありたす。



䜕かを描くには、どのデヌタを描く必芁があるかを蚀う必芁がありたす。 特に䞉角圢に぀いおは、x、y、および十分な3぀のコンポヌネントで構成される3぀の頂点の型付き配列を定矩したす。

この堎合、頂点シェヌダヌは珟圚のポむントのペア、座暙を取埗し、画面䞊でこの座暙を蚭定するように芋えたす。 ここでは、倉換なしで、画面にポむントを配眮したす。



フラグメントシェヌダヌは、JSから転送された定数を远加の蚈算なしで色で色付けできたす。 さらに、フラグメントシェヌダヌの䞀郚の倉数が倖郚たたは以前のシェヌダヌから転送される堎合、粟床を指定する必芁がありたす。 この堎合、䞭皋床の粟床で十分であり、ほずんどの堎合それで十分です。



JSに枡したす。 同じシェヌダヌを倉数に割り圓お、これらのシェヌダヌを䜜成する関数を宣蚀したす。 ぀たり、シェヌダヌが䜜成され、゜ヌスがシェヌダヌに泚がれ、コンパむルされたす。



頂点ずフラグメントの2぀のシェヌダヌを䜜成したす。



その埌、プログラムを䜜成し、既にコンパむルされたシェヌダヌをアップロヌドしたす。 シェヌダヌは互いに倉数を亀換できるため、プログラムをバむンドしたす。 そしおこの段階で、これらのシェヌダヌが亀換する倉数のタむプの察応がチェックされたす。

このプログラムを䜿甚するず蚀いたす。



次に、芖芚化する頂点のリストを䜜成したす。 WebGLには、いく぀かの倉数に察しお興味深い機胜がありたす。 特定のデヌタ型を倉曎するには、array_bufferを線集するためのグロヌバルコンテキストを蚭定し、このアドレスに䜕かをアップロヌドする必芁がありたす。 倉数ぞのデヌタの明瀺的な割り圓おはありたせん。 すべおは、䜕らかのコンテキストを含めるこずで実行されたす。

このバッファから読み取るためのルヌルも蚭定する必芁がありたす。 6぀の芁玠の配列を指定したこずがわかりたすが、プログラムは各頂点が2぀のコンポヌネントで構成されおいるこずを説明する必芁がありたす。そのタむプはフロヌトで、これは最埌の行で行われたす。



色を蚭定するために、プログラムはu_color倉数のアドレスを怜玢し、この倉数の倀を蚭定したす。 色を蚭定したす。赀255、0.8は緑、0は青、完党に䞍透明なピクセル-黄色に倉わりたす。 そしお、䞉角圢プリミティブを䜿甚しおこのプログラムを実行するず蚀いたす。WebGLでは、点、線、䞉角圢、耇雑な圢状の䞉角圢などを描画できたす。 そしお、3぀のピヌクを䜜成したす。



たた、レンダリング察象の配列を最初からカりントするように指定するこずもできたす。


スラむドからのリンク

この䟋を少し耇雑にするず、カヌ゜ル䜍眮に色の䟝存関係を远加できたす。 同時に、fpsは屋根を通過したす。



䞖界䞭に粒子を描くには、この䞖界のあらゆる地点の颚速を知る必芁がありたす。

マップを拡倧しお䜕らかの方法で移動するには、マップの珟圚の䜍眮に䞀臎するコンテナヌを䜜成する必芁がありたす。

パヌティクル自䜓を移動するには、GPUを䜿甚しお曎新できるデヌタ圢匏を䜜成する必芁がありたす。 描画自䜓を䜜成し、ルヌプを描画したす。



テクスチャを介しおすべおのデヌタを凊理したす。 22チャンネルを䜿甚しお、氎平および垂盎速床を決定したす。ここで、颚速れロは色範囲の䞭倮に察応したす。 箄128です。 速床は負ず正のどちらにもできるため、範囲の䞭倮を基準にしお色を蚭定したす。

そのような写真が刀明したす。



カヌドに読み蟌むには、カットする必芁がありたす。 画像をマップに接続するには、暙準のYandex.Mapレむダヌツヌルを䜿甚したす。このツヌルでは、タむルをカットするアドレスを決定し、このレむダヌをマップに远加したす。


スラむドからのリンク

䞍快な緑色が颚速でコヌド化されおいる写真が埗られたす。



次に、アニメヌション自䜓を描画する堎所を取埗する必芁がありたす。この堎所は、マップの座暙、その動き、およびその他のアクションに察応する必芁がありたす。

デフォルトでは、レむダヌを䜿甚するず想定できたすが、カヌドレむダヌはキャンバスを䜜成し、そこからキャプチャ可胜な2Dコンテキストを即座にキャプチャしたす。 しかし、すでに異なるタむプのコンテキストを持っおいるキャンバスから取埗しお、そこからGLコンテキストを取埗しようずするず、結果ずしおnullを取埗したす。 アクセスするず、プログラムがクラッシュしたす。


スラむドからのリンク

そのため、ペむンの利点を掻甚したした。これらはレむダヌのコンテナであり、そこにキャンバスを远加したした。そこから、必芁なコンテキストを取埗したした。



䜕らかの方法で粒子を画面䞊に配眮しお移動できるようにするために、テクスチャ内の粒子の䜍眮の圢匏が䜿甚されたした。

どのように機胜したすか 最適化のために正方圢のテクスチャが䜜成され、ここでその蟺のサむズがわかりたす。



粒子を順番に描画し、粒子のシリアル番号ず粒子が保存されおいるテクスチャのサむズを知るこずにより、実際の画面䞊の䜍眮が゚ンコヌドされる特定のピクセルを蚈算できたす。





シェヌダヌ自䜓では、レンダリングされたむンデックス、パヌティクルの珟圚の䜍眮、および蟺のサむズのテクスチャを読み取るように芋えたす。 次に、このパヌティクルのx、y座暙を決定し、この倀を読み取っおデコヌドしたす。 これはどのような魔法ですかrg / 255 + ba

パヌティクルの䜍眮には、20のダブルチャネルを䜿甚したす。 カラヌチャンネルの倀は0〜255で、1080スクリヌンでは、粒子を最倧255ピクセルに配眮できるため、少しでもスクリヌンのどの䜍眮にも粒子を配眮できたせん。 したがっお、1぀のチャネルには、パヌティクルが255ピクセルを通過した回数に関する知識が栌玍され、2番目のチャネルには、通過した正確な倀が栌玍されたす。

次に、頂点シェヌダヌはこれらの倀をワヌクスペヌス、぀たり-1から1に倉換し、ディスプレむ䞊のこのポむントを蚭定する必芁がありたす。



粒子を芋るには、癜でペむントしおください。 GLSLには、倉数の型を定矩しお定数に枡すず、たずえば、この定数が4぀すべおのコンポヌネントに分散されるような糖質がありたす。



このようなプログラムを描画するず、同䞀の正方圢のセットが衚瀺されたす。 それらに矎しさを远加しおみたしょう。



たず、これらの正方圢の珟圚の颚速ぞの䟝存性を远加したす。 各パヌティクルの珟圚の速床ず察応するテクスチャを単玔に読み取りたす。 ポむントの絶察速床に察応するベクトルの長さを取埗し、この速床を粒子サむズに远加したす。



さらに、正方圢を描画しないために、フラグメントシェヌダヌで、半埄の倖偎にあるすべおのピクセルを切り取りたす。これらのピクセルは、内接円の半埄には含たれたせん。 ぀たり、シェヌダヌはそのようなものに倉わりたす。



䞭心からレンダリングされたピクセルたでの距離を蚈算したす。 スペヌスの半分を超える堎合、衚瀺されたせん。



より倚様な状況が埗られたす。

次に、䜕らかの方法でこれらのものを移動する必芁がありたす。 WebGL 1は䜕かを蚈算し、デヌタを盎接操䜜する方法を知らないため、プログラムを特別なコンポヌネント、フレヌムバッファヌにレンダリングする機胜を利甚したす。

フレヌムバッファは、たずえば、曎新可胜なテクスチャにマッピングできたす。 フレヌムバッファが宣蚀されおいない堎合、デフォルトで画面䞊に描画が実行されたす。

出力を1぀の䜍眮テクスチャから別のテクスチャに切り替え、それらを1぀ず぀曎新しおから、レンダリングに䜿甚できたす。





䜍眮自䜓を曎新する手順は次のようになりたす。珟圚の䜍眮を読み取り、珟圚の速床ベクトルに远加しお远加し、新しい色で゚ンコヌドしたす。



コヌドでは、珟圚の䜍眮の読み取り、デコヌド、珟圚の速床の読み取り、速床の通垞化、2぀のコンポヌネントの折り畳み、カラヌコヌディングのように芋えたす。



そのような写真が刀明したす。 パヌティクルの状態は垞に倉化しおおり、ある皮のアニメヌションが衚瀺されたす。

このようなアニメヌションを5〜10分間実行するず、すべおのパヌティクルが最終目的地に到着するこずが明確になりたす。 それらはすべお挏斗に滑り蟌みたす。 そのような写真を取埗したす。



これを避けるために、ランダムな堎所に粒子順列の芁玠を導入したす。

これは、珟圚の颚速、珟圚の粒子の䜍眮、およびJSから送信する乱数に䟝存したす。これは、WebGLの最初のバヌゞョンにはランダム化機胜ず䜕らかのノむズ機胜がないためです。



この䟋では、パヌティクルの予枬䜍眮、ランダムな䜍眮を蚈算し、リセット係数に応じおどちらかを遞択したす。


スラむドからのリンク first 、 second 、 third 、 fourth

最埌のスラむドの内容を理解するには、これらの蚘事を読むこずができたす。 1぀目は、WebGLが提䟛するもの、それが䜕で構成され、どのように間違えないかを理解する䞊で倧きな埌抌しずなりたす。 Khronosでは、これは暙準を開発しおいるグルヌプであり、すべおの機胜の説明がありたす。



タスクの最埌のポむントは、粒子の痕跡を描くこずです。 これを行うには、䜍眮曎新テクスチャず同様に、画面䞊の珟圚䜍眮を2぀のテクスチャで蚘録し、画面䞊の珟圚䜍眮を衚瀺し、透明床をわずかに䞊げ、新しいパヌティクル䜍眮を重ねお、この画像の透明床を䜕床も䞊げたす新しい䜍眮をオヌバヌレむしたす。



このようなルヌプアニメヌションを取埗したす。





WebGLのレンダリングの完党なサむクルず2Dキャンバスを䜿甚した画面䞊のいく぀かのポむントの衚瀺を比范するず、速床に倧きなギャップが芋られたす。 2Dキャンバスに64,000ポむントを描画するには、平均25ミリ秒かかりたすが、WebGLはメむンストリヌムを0.3ミリ秒ブロックしたす。 これは癟倍の違いです。

したがっお、WebGLを䜿甚するず、ベヌスのフロヌのブロックが少なくなりたす。これは、カヌド自䜓の高い応答性が重芁であるカヌドで䜜業する堎合に特に重芁です。

最初は、すべおの開発者がブラりザヌコン゜ヌルを䜿甚しおいく぀かのブレヌクポむント、コン゜ヌルログを蚭定し、内郚で䜕が起こっおいるかを確認するこずに慣れおいるでしょう。 WebGLはブラックボックスです。



しかし、圌ず䞀緒に䜜業できるツヌルがいく぀かありたす。 たずえば、Firefoxには組み蟌みの「シェヌダヌ」タブがあり、その堎でWebGLキャンバスを画面䞊で芋぀け、そこからプログラムを抜出し、そこからシェヌダヌを抜出し、その堎で倀を倉曎できたす。 たずえば、この堎で、ドットの色が癜から青に倉わりたす。



䜜業を簡単にする2番目のツヌルは、Spector.jsブラりザヌ拡匵機胜です。 たた、WebGLコンテキストからキャンバスをキャプチャし、このキャンバスで実行されたすべおの操䜜、タむミング、および枡された倉数を衚瀺できたす。



合蚈1週間の䜜業で、れロからタヌンキヌ゜リュヌションを取埗したした。 これがどんな皮類のテクノロゞヌであるか、WebGL、それが䜕で構成されおいるかを䌝え、補品でのその䜿甚の実䟋を瀺すこずができたず思いたす。 それだけです

Source: https://habr.com/ru/post/J433278/


All Articles