ベクトルグラフィックスレンダリング-䞉角圢分割、ラスタラむズ、スムヌゞング、および新しいシナリオ

2013幎にリリヌスされたゲヌムTiny Thiefがリリヌスされたした。これは、アニメヌションアトラスなどを含むビルドでのビットマップグラフィックスの拒吊により、モバむルFlashAIR開発環境に倧きなノむズをもたらしたした。 。
これにより、独自のコンテンツを倧量に䜿甚し、むンストヌルファむルのサむズを最倧70メガバむト* Google Playの.apkファむルたで保存できたした。 最近、モバむルデバむスでのベクタヌグラフィックスのレンダリングのトピックおよび䞀般にハヌドりェアサポヌトを䜿甚したベクタヌのレンダリングのトピックに察する関心が再び高たり、このトピックに関する「゚ントリレベル」レベルの情報の欠劂に驚きたした。 これは、ベクトルず既存の゜リュヌションを描画する方法、およびこれらのこずを自分で行う方法に関するリファレンス蚘事です。





メむンりェむ


ベクトルを描画する最も䞀般的な方法は、すべおの圢状、曲線などを取埗し、䞉角圢化アルゎリズム閉じた茪郭を䞉角圢に分割でそれらを通過し、同じ塗り぀ぶされたオブゞェクトでさたざたなストロヌクず線を取埗し、蚘述された数孊的な近䌌衚珟を取埗するこずです図の匏。


぀たり、この方法で描かれたベクトル円は、実際にはポリゎンになりたす。 この堎合の品質基準は、結果ずしお埗られる䞉角圢の数ずサむズになりたす。



巊から右ぞ-


  1. Inkscapeの゜ヌスコヌド、
  2. 少数の䞉角圢で䞉角枬量した結果、
  3. 結果の䞉角圢

このような回避策の理由は簡単です。グラフィックカヌドは、頂点、䞉角圢、ピクセルでのみ効率的に機胜したすGPGPUは少し異なる話ですが、この文脈では、蚀及する䟡倀があるだけです。 CPUを䜿甚しお数孊的に正しいモデルの衚珟を描画する堎合、これにはさらに時間がかかりたす。 したがっお、そのたた生でレンダリングするグラフィックカヌドを䞉角枬量しお送信したす。


萜ずし穎


䞉角圢のこのような粗いレンダリングは、゚むリアシング効果の出珟に぀ながりたす-画像の゚ッゞのグラデヌションこれは䞊のスクリヌンショットではっきりず芋えたす。 この問題は、䞉角圢ずしお衚される䞍透明なゞオメトリに固有のものです。


Tiny Thiefのスクリヌンショットを芋るず、ゲヌムにこの欠点がないこずがすぐにわかりたす。オブゞェクトの端は矎しく滑らかです。






珟地調査


Adreno Profiler、NVIDIA PerfHUD ES、およびUnityを䜿甚しお、以䞋で説明するすべおのこずをテストしたした提案された゜リュヌションの機胜を確認したす。


カラヌグリッドモヌドを有効にするず、Adreno Profilerに衚瀺される内容は次のずおりです。




぀たり、䞉角圢分割の同じ方法でレンダリングしたす。 頂点は、テクスチャ頂点のカラヌパラメヌタなしで盎接ペむントされたす。


アルファバッファの内容は次のずおりです明らかに、Adreno GPUには「アルファバッファ」などがありたす。



オブゞェクトの゚ッゞに沿っお、薄い単䞀ピクセルのストリップ。 興味深いこずに、アルファチャネルは隣接するオブゞェクト間の゚ッゞで「癜」です癜い背景は色付きの文字です。぀たり、ロゎ党䜓が1぀のパスで描画され、そのようなオブゞェクト内のスムヌゞングは​​わずかに異なる方法で実装されたす。


シェヌダヌ


{ lowp vec4 fcolor; //    color  fcolor = color; //   ,    factor fcolor.a *= factor.a; fcolor = fcolor; gl_FragColor = fcolor; } 

スムヌゞングの本質は倚かれ少なかれ明確です-䞉角圢化するずき、オブゞェクトの゚ッゞに沿っお现い䞉角圢のセットを远加したす。


どんなに写真を近づけようずしおも、これらのずるい现い䞉角圢を芋぀けるこずはできたせんでした。 しかし、幞いなこずに、Adfno ProfilerはPerfHUDずは異なり、ゞオメトリをテキスト圢匏で゚クスポヌトできたす。


分割組立


単玔なパヌサヌを䜜成した埌、Unityで元のメッシュを埩元するこずが刀明したした。 しかし、奇劙な写真が埅っおいたした。




スムヌゞングのないフレヌム。 グリッドビュヌモヌドでは、塗り぀ぶしの䞉角圢も衚瀺されたせん。




長い間、䜕が問題なのか理解できたせんでした。 塗り぀ぶし䞉角圢が反察方向に回転しおいるこずがわかりたした。 これは、反察偎からロゎを芋るず明らかになりたす。





たた、ロゎの芁玠の間には、グラデヌションで塗り぀ぶされた空の線がありグラデヌションは頂点を察応する色でペむントするこずによっお䜜成されたす、スムヌゞングがありたせん。




シェヌダヌでバックフェヌスカリングを削陀するず、結果ずしお埗たいものが埗られたす。


しかし、興味深い機胜が発生したす-このオブゞェクトをカメラに近づけるず、スムヌゞングが目立ちやすくなり、ブラヌのように芋えたす。


぀たり、画面のサむズに応じお、所定の堎所で毎回䞉角枬量が行われ、このオブゞェクトのサむズの倉曎を意味したせん。 䞉角圢のサむズは、合蚈幅が1画面ピクセル以䞋になるように蚈算されたす。

画面䞊のほずんどすべおのオブゞェクトは同じ方法で描画されたす。 䟋倖は背景であり、テクスチャで䞀床レンダリングされたす。



統蚈


キャラクタヌのレンダリングに関する芁玄情報を芋るのは十分に興味深いものです。平均しお、䞉角圢の圢の各ヒヌロヌガヌド、料理人は玄3〜4000個の䞉角圢です。 良質の䜎ポリ3Dモデルのようなものです。 グリッドは非垞に密集しおいるため、オブゞェクトはテクスチャで描画されおいるようです。




ロゎはほが9000の䞉角圢を占めおいたす。 描画呌び出しの合蚈数は平均で玄100です背景がテクスチャずしお描画されない堎合ははるかに倧きくなりたすが、FPSは叀いZTE V811Beeline smart 2でも安定しお最倧です。


䞀般に、ベクタヌグラフィックスを貯金箱に描画する最初のそしお䞻芁な方法を取りたす。
ベクトル画像を䞉角圢分割し、ゞョむントに沿っお䞭間色で现い境界線を䜜成し、゚ッゞに沿っお薄い半透明のストリップを䜜成したす。


逆さた


SDF


ベクトル画像の色の数に制限を蚭定するず、たったく異なる方法を䜿甚できたす。 単玔なベクトルモノクロアむコンがあるずしたす。



笊号付き距離フィヌルドを䜿甚するず、品質をほずんど損なうこずなく「圧瞮」できたす。 䞀番䞋の行は、テクスチャ自䜓を保存するのではなく、アむコンの境界たでのピクセルの距離に関する情報を保存するずいうこずです。 通垞、境界の倀は0.5に等しいず芋なされたす。 アむコンの「内偎」にあるず考えられるものすべお。 少ないのは「倖偎」です。 実際、どちらの方法で境界線を䞊回るかは問題ではありたせん。内偎を0.5未満、倖偎を0.5以䞊にするこずができる堎合がありたす。 わかりやすくするため癜い背景に黒いアむコン、そのようなオプションのみを瀺したす。




このように塗り぀ぶされたサむコロは次のようになりたす。



通垞のがかしずの違いは、珟圚のピクセルず境界線の間の最小距離を芋぀けるこずです。いずれの堎合も、法線に沿った距離を蚈算したすポむントからラむンたでの最小距離は垞に垂線によっお決たりたす。 ぀たり、テクスチャのグラデヌションは、最も近い境界線の法線の方向を衚したす。



むンタヌネット、特にハブには、SDFに関する倚くの蚘事がありたす。蚘事の最埌にそれらを掲茉したす。



この写真は、通垞のテクスチャずSDFの2぀のオプションの品質の違いを明確に瀺しおいたす。 通垞の画像を拡倧するず、がかしがはっきりず芋えるようになりたす。 いずれにせよ、SDFテクスチャを増やすこずにより、シャヌプな境界が埗られたす。 さらに、テクスチャサむズを半分に瞮小しおも、アヌティファクトの存圚はほずんど芋えないたたです生のSDFテクスチャの品質を向䞊させるこずに぀いお別の蚘事を曞くこずができたす。 アヌティファクトは、通垞のテクスチャずは察照的に、アむコンの斜めの端に滑らかなはしごずしお衚瀺されたす。 これは、ピクセルが正確に氎平および垂盎に移動するずいう事実によるものであり、画像サむズが瞮小されるず、2぀の垂盎な盎線の助けを借りお斜めの盎線を近䌌する粟床も䜎䞋したす法線ベクトルを境界に近䌌するこずを思い出させおください。


レンダリング甚のシェヌダヌは、テクスチャを読み取るよりも少し耇雑になりたす。 実隓では、次のような倚くの異なるオプションを詊したした。 たた、蚘事[2]の倉圢で、䞀般的には次のようになりたす。


 float4 frag (v2fSDF f) : SV_Target { float2 uv = f.uv; half4 texColor = tex2D(_MainTex, uv); //   -  half distance = texColor.a; //    half smoothing = _Smoothing; //    -   _Dilate = 0.5 half2 range = half2(_Dilate - smoothing, _Dilate + smoothing); //   (   - ) half totalSmoothing = smoothstep(range.x, range.y, distance); half3 rgb = f.color.rgb; return float4(rgb, totalSmoothing); } 

この堎合、テクスチャのRBGチャネルが排出され、蚈算に関䞎しないこずに泚意しおくださいこれに぀いおは埌で説明したす。 _ スムヌゞングを画面䞊の珟圚のテクスチャサむズに手動で蚭定できたすただし、メッシュを介したレンダリングの堎合ず同じように、増加には同じ問題がありたす、たたはcg関数fwidthを䜿甚したす。 「画面䞊のアむコンの盞察的なサむズに合わせたす。


SDFメ゜ッドの䞻な制限は゜ヌスシンボルの「バむナリ」1色性の必芁性であるため、テキストをレンダリングするずきに最もよく䜿甚されたす。同じSDFテクスチャの凊理オプションを調敎および倉曎するこずにより、ストロヌク、シャドり、ブラヌなどを䜜成できたす [1]。 SDFを䜿甚するあたり䞀般的ではない方法は、モノクロのアむコンを描くこずですサむコロの堎合のようにが、ほずんどの堎合、これはテキストシンボルの特別な堎合です。
このアプロヌチの別の欠点は、鋭い゚ッゞず角床が倱われるこずです。




巊偎は元のテクスチャです。 右-瞮小サむズのSDF

たた、蚘事[3]のテキストを䜿甚した別の䟋


利甚可胜になった問題を解決する


鋭角を保持する同様のアルゎリズムの実装䟋がありたす[4] [5]


アルゎリズムの抂芁は次のずおりです。


生のSDFは角が䞞くなりたす。ピクセルが遠くなるほど䞞くなるからです。 これは、角に垂盎を描くこずができないために発生したす関数の導関数はこの点には存圚したせん-倚くのピクセルは、䞭心が角床である円の半埄に沿った距離を考慮したす。 これは、滑らかに走る曲線の切れ目をチェックしお、シンボルのすべおのコヌナヌを远跡するこずで回避できたす。 次に、真理倀衚を䜿甚しお、角床の象限を塗り぀ぶすかどうかを決定したす。 ぀たり、通垞、コヌナヌは異なるチャネルに蚘録された亀差したSDFカヌドによっお塗り぀ぶされ、最終的なピクセル倀は3぀のチャネルからのベクトルの䞭倮倀によっお蚈算されたす。


もちろん、蚘事党䜓を1぀の段萜の90ペヌゞに収めるこずはできたせん。そのため、完党に参照するこずをお勧めしたす[5]。


チャネルに散圚するさたざたなフィヌルドの亀差点で同様のこずをしようずする以前の詊みがありたしたが、䞀郚のオプションは、説明した䟋ずは異なり、実際にそこに残っおいないため、圱を远加したり、ストロヌクを倪くしたり、シンボルの倪さを増やしたりするこずを意味したせん距離フィヌルド自䜓。



少ないチャンネル-より高い粟床


Twitterには、フックたたは詐欺垫によっお䌌たようなこずをしおいるが、1぀のチャネルを持぀友人がいたす。




圌のtwitterのさたざたなリンクを芋るず、いく぀かの実装オプションを芋぀けるこずができたす。 私が理解しおいるように、アプロヌチは暙準のSDFずは異なり、実際の境界たでの距離を䜿甚せずコヌナヌ䞭心の呚りの䞞めを回避するため、わずかに再解釈された図を䜿甚し、そのコヌナヌはさらに続きたす。 これにより、角の䞞みやいく぀かのチャンネルを取り陀き、シェヌダヌを簡玠化し、そのような図を衚瀺するために必芁な情報の総量を枛らすこずができたす。


このコンパニオンには、GPUのベゞェ曲線の距離フィヌルドをリアルタむムで考慮するシェヌダヌもありたすが、1぀の曲線パラメヌタヌで蚭定され、その匏は「シェヌダヌに盎接」あるでもデスクトップコンピュヌティングパワヌが必芁です。 蚭定ずコヌドをひねるず、ペむントや倉調なしで距離フィヌルド自䜓を芋るこずができたす。




これらの方法の共通の本質は、キャラクタヌの境界を定矩する曲線を分析するこずです。



基本に戻る


3番目の方法-シンボルに関するラスタ情報を保存するのではなく、いわば「ストヌブから」描画する-曲線のベクトル衚珟から盎接描画するこずもできたす。 問題は、パフォヌマンスを損なうこずなく曲線情報をグラフィックカヌドに転送するこずが比范的難しいこずです。 同様の方法を説明する蚘事がいく぀かありたす。


ベクタヌテクスチャを䜿甚したGPUテキストレンダリング [3]。Microsoftにも特蚱がありたす。


芁するに、䞀番䞋の行は次のずおりです。


シンボルをセルに分割し、セルごずに、異なる角床で発射され、このセルず亀差する光線ず曲線の亀差点のマップを䜜成したす。 亀差点の数ず、これらの亀差点が発生した距離を調べたす。 曲線デヌタは、ベゞ゚曲線の座暙が蚭定されたしわくちゃのテクスチャずしお保存されたす。 1぀のベゞェ曲線は、この曲線の次数に応じお3たたは4パラメヌタヌです。 4番目のパラメヌタヌを超えるず、通垞、曲線は取埗されたせん。 シェヌダヌは、珟圚のレンダリングされたセルずこのセルに存圚するテクスチャパラメヌタヌに応じお、参照テクスチャから必芁なピクセルを読み取り、それらを䜿甚しおGPUの曲線の分析圢匏を埩元したす。


すべおがバラ色ではありたせん。


このようなアプロヌチの欠点は、比范的倚数のテクスチャ読み取り操䜜を䜿甚するこずです。 モバむルデバむスでタップがかしブラヌを䜿甚したシャドりのリアルタむムレンダリングを䜕らかの方法で凊理したしたが、Dependent Texture ReadsDTS-ロシア語で䞀般に受け入れられおいるアナログは芋぀かりたせんでしたはパフォヌマンスを倧幅に䜎䞋させたした。 非垞に粗雑な堎合-DTSは、テクスチャの読み取り座暙がフラグメントシェヌダヌでのみ認識されるようになるず、぀たりピクセルを盎接レンダリングするずきに発生したす。 通垞、フラグメントシェヌダヌでのテクスチャの高速読み取りは、頂点シェヌダヌの実行盎埌にピクセルの特定の補間されたテクスチャ座暙が刀明するずいう事実によっお決たりたす。぀たり、ビデオカヌドは事前に目的のテクスチャピクセルを読み取り、ピクセル倀を「無料」で提䟛したす。 アルゎリズム、動䜜、および䜜業の皋床は、䞻にこれらのシェヌダヌが実行されるアむロンによっお決たりたす。 OpenGL ES 3.0+では、DTSのパフォヌマンスの問題の倧郚分は解決されおいるようですが、珟時点ではモバむルデバむスの玄半分がOpenGL ES 2.0で動䜜するため、珟時点では優れたハヌドりェアを期埅する䟡倀はありたせん。
 ゜ヌス2017幎2月6日 


特蚱を取埗したマむクロ゜フトのアプロヌチでは、4぀のチャネルを䜿甚しおセル内のピクセルの色を゚ンコヌドできるこずは泚目に倀したす。 そしお、最初に興味を持ったのは、たさにカラヌベクトル画像のレンダリングでした。



さらに生きる方法


䞊蚘の方法には、次の欠点がありたす。


  1. メッシュ䞉角圢分割法を䜿甚した画像の品質は、䞉角圢の数に倧きく䟝存したす。これにより、割り圓おられたメモリずビデオカヌドの負荷が増加したす小さいながらも高密床のグリッドは、クワッドに描かれた同じサむズのテクスチャよりもGPUに負荷がかかりたす。
  2. SDFそのものは、マルチカラヌ芁玠をレンダリングする胜力を意味するものではありたせん。 条件の1぀は、「バむナリ」゜ヌスむメヌゞです。
  3. さたざたなベクトルパラメヌタを定矩するピクセルぞの「ランダムアクセス」の方法は、GPU偎で倚くの凊理胜力を必芁ずしたす。特に、远加のテクスチャ読み取りに倚くの時間が費やされたす。

したがっお、私は同じSDFの原理に基づいお、マルチカラヌのベクトルグラフィックスをレンダリングするためのわずかに異なる方法を提䟛したいず考えおいたした。


SDFのSecond Life


SDFは、テキスト文字の単色レンダリングず同矩語になりたした。 ただし、ベクタヌ画像をモノクロレむダヌのセットずしお衚珟し、同じSDFテクスチャを䜿甚するず、任意の耇雑さず色のベクタヌ画像を描画できたす。 ぀たり、初期むメヌゞを䞀連のモノクロレむダヌに単玔に分割したす。


䟋-レむダヌにカットされたケニヌの人気セットのボックスは次のようになりたす。



これは、SVGファむルの倖芳です。 レむダヌは互いに重なり合っおいないが、互いに「結合」しおいるこずに気付くかもしれたせん。 Inkscapeを䜿甚しおこのようなベクタヌ画像を衚瀺するず、これらのレむダヌの同様のドッキングに固有のアヌティファクトが明確に衚瀺されたす。




アヌティファクトの存圚は、ベクタヌグラフィックスの䜜成方法によっお異なりたすが、ここでは、このオプションを䜿甚しおみたしょう。


行動する


レむダヌごずに、独自のSDFテクスチャを䜜成し、SVGファむルでの順序ず同じ順序でレむダヌを重ねおみたしょう。




巊から右-アンチ゚むリアシングを有効にしたSVGむンポヌタヌ、「レむダヌド」SDF、初期テクスチャヌの増加。 SVG ImporterはInkscapeからSVGを適切に解析できたせんでしたが、それはポむントではありたせん。


䞡方のオブゞェクトが非垞に近い堎合、違いは次のようになりたす。




䞉角枬量



パフSDF



他のすべおの方法ず比范した堎合のこの方法の䞻な欠点は、倧幅なオヌバヌドロヌです。 このボックスを描画するには、4぀のフルサむズレむダヌを重ねお配眮し、さらに5番目のレむダヌに小さな四角圢小さなダッシュを配眮する必芁がありたす。 最悪の堎合、オヌバヌドロヌはベクトル画像のレむダヌ数に正比䟋したす。 デバむスの解像床が高いほど、レンダリングが遅くなりたす。

ただし、SVGファむルをメッシュに解析するためのほずんどのパッケヌゞずは異なり、事前に準備されたテクスチャはかなり少ないスペヌスを占有したす。 この点で、Scaleformはさらに進化したした。シヌンをロヌドするずきに、事前に䜜成されたファむルでアプリケヌションアヌカむブを詰たらせるこずなく、すべおのメッシュをその堎で生成したした。 比范のために、初期ボックスサむズは4 Kbのテキストです。぀たり、ベクトル画像のスムヌゞングで事前に組み立おられたメッシュは、このベクトル圢状を蚘述する生のテキストの11倍のスペヌスを占有したす。


オプションは䜕千もありたす


私はたた、カラヌ画像をSDFビュヌに倉換する別の方法を芋぀けたした。 [6]䞀番䞋の行は、色にビットプレヌンを䜿甚するこずです。 ビットカヌドは、色の明るさをビット単䜍でレむアりトしたす。

぀たり、茝床ビットが順番に取埗され、個別のバむナリテクスチャに入れられたす。 8぀のテクスチャが必芁な画像チャンネルは1぀だけです。 ぀たり、透明床のないカラヌ画像ごずに24のテクスチャです。

さらに進んで、それぞれのバむナリテクスチャを8ビットSDFテクスチャずしお提瀺するず、初期画像を完党に衚珟するには、24個の8ビットテクスチャが必芁であるこずがわかりたす24個のシングルビットテクスチャではなく、ビットカヌドに分解した盎埌に取埗されたす。

SDF凊理されたビットカヌドから初期カラヌ画像を埩元するプロセスは次のずおりです。


  1. 各チャネルの各ビットマップに぀いお、珟圚のSDFピクセル倀がチェックされたす。
  2. 0.5未満の堎合、元のビットは1であり、0より倧きい堎合この堎合の0.5は抜象倀であり、8ビット敎数が127の倀ず比范されたす
  3. すべおのビットのすべおの倀が順番に収集され、各チャネルが個別に埩元されたす。 たずえば、赀チャネルの珟圚のピクセルのビット倀が01110011である堎合、赀チャネルの茝床は115です。
  4. 同じ方法で珟圚のピクセルのすべおのチャネルを通過したす。
  5. 3぀のチャネルで色の倀を埩元したす。


このアルゎリズムは非垞に泚意が必芁ですが、実際、品質は良くありたせん。



アヌティファクトは、カラヌチャンネルをビット単䜍のコンポヌネントにカットするこずで、SDFテクスチャの瞮小コピヌの保存䞭の粟床䜎䞋の問題が悪化するずいう事実により衚瀺されたす。 私の意芋では、この方法はこの理由のために特に適甚されたせん。 しかし、もう1぀の欠点は、1぀のオリゞナルカラヌ画像に24個の8ビットSDFテクスチャを保存する必芁があるこずです。


たずめ


すぐに䜿甚できる新しい゜リュヌションを提䟛するこずはできたせんが、パスマヌキングのパレットを䜿甚しおSDF゚ンコヌディングを䜜成するためのアむデアず詊みがありたす。これにより、さたざたなチャネルの倚数の異なるテクスチャを保存し、オヌバヌドロヌを枛らすこずができたす


蚘事はすでに非垞に倧芏暡であるこずが刀明したため、コンテンツを倧幅に削枛する必芁がありたした。 私が蚀わなかったこずから



  1. Signed Distance Field
  2. UTF-8 SDF
  3. GPU text rendering with vector textures
  4. Sharp Corners with Signed Distance Fields Fonts
  5. Shape Decomposition for Multi-channel
    Distance Fields
  6. Signed Distance Field rendering of color bit planes

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


All Articles