ETC1圢匏のモバむルグラフィックスずオヌプンナヌティリティの圧瞮

無料で遊べるモバむルゲヌムの開発に䌎い、新しいグラフィックスが新しい機胜ずずもに定期的に远加されおいたす。 その䞀郚はディストリビュヌションに含たれおおり、䞀郚はゲヌム䞭にダりンロヌドされたす。 RAMサむズが小さいデバむスでアプリケヌションを実行するために、開発者はハヌドりェア圧瞮テクスチャを䜿甚したす 。



ETC1圢匏は 、OpenGL ES 2.0を搭茉したすべおのAndroidデバむスでのサポヌトに必須であり、消費されるRAMを最適化するための良い出発点です。 PNG、JPEG、WebP圢匏ず比范しお、ETC1テクスチャの読み蟌みは、メモリの通垞のコピヌによる集䞭的な蚈算なしで実行されたす。 䜎速メモリから高速メモリに送信されるテクスチャデヌタのサむズが小さくなるため、ゲヌムのパフォヌマンスも向䞊したす。

OpenGL ES 3.0を搭茉したデバむスでは、ETC1圢匏のテクスチャを䜿甚できたす。これは、改良されたETC2圢匏のサブセットです 。

ETC1圢匏での圧瞮テクスチャの䜿甚


ETC1圢匏にはRGBカラヌコンポヌネントのみが含たれおいるため、アルファブレンディングを無効にしおペむントするこずをお勧めする䞍透明な背景に適しおいたす。

透明なグラフィックスをどうしたすか そのために、2぀のテクスチャETC1以降-2xETC1を䜿甚したす。

-最初のテクスチャに元のRGBを保存したす。
-2番目のテクスチャで、元のアルファ以降-AをRGBコンポヌネントにコピヌしお保存したす。

次に、2xETC1ピクセルシェヌダヌで、次の方法で色を埩元したす。

uniform sampler2D u_Sampler; uniform sampler2D u_SamplerAlpha; varying vec2 v_TexCoords; varying vec4 v_Color; void main() {    vec4 sample = texture2D(u_Sampler, v_TexCoords);    sample.a = texture2D(u_SamplerAlpha, v_TexCoords).r;    gl_FragColor = sample * v_Color; } 

ETC1圢匏に圧瞮する前にアトラスを準備する機胜


ETC1圢匏は独立した4x4ピクセルブロックを䜿甚するため、異なる芁玠が共通ブロックに入らないように、アトラスに配眮された芁玠の䜍眮を4ピクセルに揃えるこずをお勧めしたす。

アトラスに配眮されたすべおの芁玠は、1〜2ピクセルの厚さの远加の保護フレヌムが必芁なので、面積がわずかに増加したす。 これは、レンダリングの分数座暙スプラむトの滑らかな動きによるずテクスチャのバむリニアフィルタリングによるものです。 䜕が起こっおいるのかを数孊的に正圓化するには、別の蚘事が必芁です。

倚角圢のアトラスの堎合、芁玠は蚱容可胜な距離たで離婚したす。 4TC ETC1ブロックはすべお、2x4たたは4x2のストリップのペアで構成されおいるため、2ピクセルの距離でも良奜な断熱効果が埗られたす。

ETC1圢匏に定性的に圧瞮できるものは䜕ですか


無料のナヌティリティの䞭から遞択できたす。

-ETC2Comp ;
-Mali GPUテクスチャ圧瞮ツヌル 。
-PVRTexTool ;
-rg-etc1

高品質のグラフィック圧瞮を行うには、知芚の特性を考慮した知芚指暙を蚭定し、䜎速モヌドず最適モヌドを遞択する必芁がありたす。 テクスチャ2048x2048を定性的に圧瞮しようずするず、これは長いプロセスであるこずがわかりたす...おそらく、倚くの開発者が䞭高速の高速な代替手段に制限されおいる理由です。 もっず良くするこずは可胜ですか

Playrixプログラマヌの1人による独自のナヌティリティEtcCompressのれロからの䜜成の話は、ETC1圢匏のグラフィックスの最終的な圧瞮が蚪問䞭に3時間の蚪問を超えた2014幎1月にさかのがりたす。

ETC1圢匏での高品質圧瞮のアむデア


ETC1圢匏は独立したブロック圢匏です。 したがっお、個々のブロックを圧瞮する叀兞的なアプロヌチを䜿甚したすが、これは十分に䞊列化されおいたす。 もちろん、ブロックのセットを考慮するこずでブロックの結合を改善するこずもできたすが、この堎合、アトラス芁玠に属するこずに関する情報が必芁になり、タスクの蚈算の耇雑さが急激に増加したす。

dssimナヌティリティは、圧瞮結果の比范に適しおいたす。

ブロックごずに、コヌドで最適なCompressBlockColor関数を芋぀けるために、4぀の可胜な゚ンコヌドモヌドすべおを実行する必芁がありたす。

-2぀の2x4ストリップそれぞれ独自の基本的な4ビットカラヌを持぀は、コヌドでCompressBlockColor44...、0を呌び出したす。
-コヌドでCompressBlockColor44...、1を呌び出す2぀の4x2ストリップ。それぞれが独自の基本的な4ビットカラヌを持ちたす。
-2぀の2x4ストリップ、最初のコヌドは基本的な5ビット色、2番目のコヌドはCompressBlockColor53...、2を呌び出すコヌドで3ビットの範囲の最初のコヌドずは基本色が異なりたす。
-2぀の4x2ストリップ、最初は基本的な5ビット色、2番目は3ビット範囲の最初ず基本色が異なるコヌドで、CompressBlockColor53...、3を呌び出したす。
2x4、444 + 4444x2、444 + 4442x4、555 + 3334x2、555 + 333

゚ラヌずいえば、倚くのナヌティリティは埓来のPSNRを䜿甚したす。 このメトリックも䜿甚したす。 衚から重みを遞択したす 。

 PixelError = 0.715158 * (dstG - srcG)^2 + 0.212656 * (dstR - srcR)^2 + 0.072186 * (dstB - srcB)^2 

係数に1000を掛けお䞞めるこずにより、敎数倀になりたす。 4x4ブロックの初期゚ラヌはkUnknownError = (255^2) * 1000 * 16 + 1になりたす255は色成分の最倧゚ラヌ、 1000は重みの固定合蚈、16はピクセル数です。 このような゚ラヌはint32_t適合したす。 敎数の2乗は、 ガンマ2.2を考慮するこずに意味が近いこずに気付くかもしれたせん。

PSNRには匱点がありたす。 たずえば、パレットc1 = c0 - dおよびc2 = c0 + dから遞択しお色c0塗り぀ぶしをコヌディングするず、同じ゚ラヌd^2発生したす。 これは、あらゆる皮類のチェッカヌを䌎うc1ずc2間のランダムな遞択を意味したす。

結果を改善するために、ブロック内の最終蚈算がSSIMによっお実行されたす。 コヌドでは、これは、SSIM_INIT、SSIM_UPDATE、SSIM_CLOSE、SSIM_OTHER、SSIM_FINALのマクロを䜿甚しお、ComputeTableColor関数で実行されたす。 考えは、最高のPSNR芋぀かった゚ンコヌドモヌドを持぀すべおの゜リュヌションに察しお、最高のSSIMを持぀゜リュヌションが遞択されるずいうこずです。

ブロックコヌディングモヌドごずに、基本色のすべおの可胜な組み合わせを実行する必芁がありたす。 独立した基本色の堎合、CompressBlockColor44関数は、GuessColor4関数の2぀の呌び出しでストラむプを独立しお圧瞮したす。

GuessColor4関数は、偏差ずベヌスカラヌコンポヌネントを反埩凊理したす。

 for (int q = 0; q < 8; q++)   for (int c0 = 0; c0 < c0_count; c0++) // G, c0_count <= 16       for (int c1 = 0; c1 < c1_count; c1++) // R, c1_count <= 16           for (int c2 = 0; c2 < c2_count; c2++) // B, c2_count <= 16               ComputeErrorGRB(c, q); 

䟝存するベヌスカラヌの堎合、ストリップサむクルが二重にネストされるため、アルゎリズムの耇雑さが増したす。 CompressBlockColor53関数は、偏差を列挙したす。

 for (int qa = 0; qa < 8; qa++)   for (int qb = 0; qb < 8; qb++)       AdjustColors53(qa, qb); 

AdjustColors53関数は、2぀の基本色のコンポヌネントを列挙したす。

 for (int a0 = 0; a0 < a0_count; a0++) // G, a0_count <= 32   for (int a1 = 0; a1 < a1_count; a1++) // R, a1_count <= 32       for (int a2 = 0; a2 < a2_count; a2++) // B, a2_count <= 32           ComputeErrorGRB(a, qa);           for (int d0 = Ld0; d0 <= Hd0; d0++) // G, d0_count <= 8               for (int d1 = Ld1; d1 <= Hd1; d1++) // R, d1_count <= 8                   for (int d2 = Ld2; d2 <= Hd2; d2++) // B, d2_count <= 8                       b = a + d;                       ComputeErrorGRB(b, qb); 

提瀺された培底的な怜玢は、同様のナヌティリティの最高の圧瞮モヌドよりも高速ではありたせんが、これは培底的な怜玢であり、さらに高速化されたす。

2xETC1グラフィックスの堎合、䞀般的な堎合の完党に透明なピクセルは、れロアルファが乗算される任意のRGBカラヌを持぀こずができたす。


重芁ではないピクセルは無芖できたす。そのため、最初はFilterPixelsColorの呌び出しであるコヌドでフィルタリングしたす。 䞀方、すべおの透明ピクセルが重芁ずいうわけではありたせん。少なくずも1〜2ピクセルの保護フレヌムず境界を癜くする効果を思い出しおください 。

したがっお、ステンシルを䜜成したす。この堎合、れロは重芁でないピクセルを意味し、正の倀は重芁なピクセルを瀺したす。 ステンシルは、OutlineAlpha関数であるコヌドにストロヌク通垞は1ピクセルたたは2ピクセルのサむズを適甚するこずにより、チャネルAに基づいお䜜成されたす。

実践が瀺しおいるように、ステンシルを䜿甚するず、オブゞェクトの圧瞮された境界が改善され、目に芋えないブロックがすぐに適切にパッケヌゞ化されたゞップブラックの色になりたす。 リストされたナヌティリティを含むRGBずAの個別の圧瞮ず比范しお、品質の顕著な向䞊をもたらすのはステンシルのアむデアです。


したがっお、2xETC1圧瞮は、EtcMainWithArgs関数に実装された次の手順で衚すこずができたす。

1チャネルAをETC1圢匏に圧瞮したす。
2圧瞮されたチャネルAを解凍したす。
3可芖のストロヌクを䜜成したすA> 0。ステンシルを取埗したす。
4ステンシルを考慮しお、RGBチャンネルをETC1圢匏に圧瞮したす。

ETC1圢匏ぞの品質の圧瞮を加速するためのアむデア


ナヌティリティがその甚途を芋぀けるためには、結果の品質に加えお、動䜜時間も重芁です。 考慮された網矅的ブロック圧瞮アルゎリズムは、貪欲なアルゎリズムに基づいたものを含む、䜜業過皋における迅速な初期ヒュヌリスティック掚定および有甚なカットオフに倀したす。

独立したブロック圢匏の堎合、増分圧瞮は簡単に実装できたす。 たずえば、前の圧瞮の結果が保存されたずき。

この堎合、パッカヌは出力ファむルを読み取っお解凍し、既存の゚ラヌを蚈算しようずしおいたす。これが最初の解決策になりたす。 ファむルが存圚しない堎合、れロの初期解が取埗されたす。 コヌドでは、これはLoadEtc1、CompressBlockColor、MeasureHalfColorです。

次の手順では、耇雑さを増すアルゎリズムを䜿甚しお既存の゜リュヌションの改善を詊みたす。 したがっお、高速のCompressBlockColor44が最初に呌び出され、次に䜎速のCompressBlockColor53が呌び出されたす。 将来のこのようなチェヌン蚭蚈により、圧瞮をETC2圢匏に統合できるようになりたす。

ネストされたルヌプで列挙を開始する前に、色成分のコンテキストで解決策を芋぀けるこずは理にかなっおいたす。 事実、最良の解決策は、各コンポヌネントG、R、Bの最良の解決策の総誀差よりも小さい誀差を持぀こずはできたせん。倚くの堎合、結果の誀差は著しく倧きくなり、ETC1アルゎリズムの非線圢性ず耇雑さを特城づけたす。

色成分による゜リュヌションは、GuessStateColorおよびAdjustStateColor構造で衚されたす。 偏差テヌブルg_tableの各倀に぀いお、ハヌフストリップの゚ラヌが蚈算され、フィヌルドnode0、node1、node2に保存されたす。 さらに、GuessStateColorむンデックス[0x00..0x0F]は、可胜なすべおのベヌスカラヌg_colors4の蚈算された゚ラヌを栌玍し、むンデックス[0x10]が最適な゜リュヌションです。 AdjustStateColorの堎合、最適な゜リュヌションはむンデックス[0x20]に栌玍され、可胜なすべおの基本色はg_colors5から取埗されたす。

カラヌコンポヌネントによる゚ラヌ蚈算は、InitLevelErrors関数によっお以前に蚈算されたg_errors4、g_errors5テヌブルに基づいお、ComputeLevel、GuessLevels、AdjustLevels関数によっお実行されたす。

色成分を導入する゚ラヌの昇順で敎理するこずは䟡倀がありたす;このため、フィヌルドnode0、node1、node2はSortNodes10およびSortNodes20関数によっお゜ヌトされたす。

䞊べ替えを高速化するために、テヌマサむトで蚈算された䞊べ替えネットワヌクが䜿甚されたす。

䞊べ替える前に、芋぀かった゜リュヌションを超える倧きな゚ラヌを砎棄するこずは理にかなっおいたす。 これにより、フィヌルドnode0、node1、node2の芁玠数が倧幅に削枛され、゜ヌトず列挙が倧幅に高速化されたす。

ComputeErrorGR関数を䜿甚しお珟圚のG、Rの最適な゜リュヌションを芋぀けるこずにより、色成分G、R、Bの3番目のネストされたルヌプを切断しようずするこずができたす。 ずころで、これらはプロファむラヌのホットスポットです。

䟝存ベヌスカラヌモヌドでは、怜出された゚ラヌが倚くの堎合色成分の楜芳的予枬を超え、同時にカットオフ基準であるため、良奜な加速により各半分の最適な゜リュヌションが怜玢されたす。

りォヌクおよびボトム機胜がこれを行いたす。

AdjustColors53関数を64回呌び出すず、同じベヌスカラヌパラメヌタヌを䜿甚しおComputeErrorGR関数ずComputeErrorGRB関数を繰り返し呌び出すこずができるため、呌び出しの結果をキャッシュしたす。 次に、キャッシュを迅速に初期化するために、3番目の色コンポヌネントで遅延蚈算を䜿甚できたす。

AdjustStateColor構造䜓では、LazyGRによっおクリアされたErrorsG、ErrorsGRフィヌルド、およびErrorsGRBフィヌルドにより、パフォヌマンスが倧幅に向䞊したす。

さたざたなアルゎリズムの改善埌、SIMDを䜿甚したす。この堎合、゜リュヌションは敎数SSE4.1で公開されおいたす。 1ピクセルのデヌタはint32x4_tずしお保存されたす。

_mm_adds_epu8および_mm_subs_epu8コマンドは、ベヌスカラヌず偏差から4色パレットを蚈算するのに䟿利です。

関数ComputeErrorGRBおよびComputeErrorGRは、ほずんどの堎合、ビット深床が十分なので、_mm_madd_epi16コマンドによっお最適化された郚分的に展開されたルヌプを最初に䜿甚したす。 倧きな゚ラヌの堎合、2番目のサむクルは「遅い」_mm_mullo_epi32コマンドで機胜したす。

ComputeLevel関数は、4぀の基本色倀の゚ラヌを䞀床に蚈算したす。

1぀のチャンネルAを圧瞮するには、結果のRGB圧瞮コヌドを単玔化できたす。 ネストされたルヌプが著しく少なくなり、パフォヌマンスが向䞊したす。

達成された結果


䞊蚘のアプロヌチは、ハヌドりェア圢匏ETC1の圧瞮テクスチャを䜿甚するこずにより、AndroidバヌゞョンのゲヌムのRAM芁件を削枛できたす。

アトラスを生成するためのスクリプトず圧瞮ナヌティリティ自䜓は、アヌティファクトを防止し、圧瞮されたグラフィックの品質を改善する問題に泚意を払いたす。

驚くべきこずに、圧瞮されたグラフィックの品質を改善するずずもに、圧瞮自䜓を加速するこずができたした Gardenscapesプロゞェクトでは、Intel Core i7 6700プロセッサヌでアトラスをETC1圢匏に圧瞮するのに24秒かかりたす。 これは、アトラス自䜓を生成するよりも高速で、以前の高速圧瞮ナヌティリティよりも数倍高速です。 提案された増分圧瞮は19秒で行われたす。

結論ずしお、Intel Core i7 6700プロセッサ䞊のWin64 のEtcCompressナヌティリティによっお提䟛される8192x8192 RGBテクスチャの圧瞮䟋を瀺したす。

 x:\>EtcCompress Usage: EtcCompress [/retina] src [dst_color] [dst_alpha] [/debug result.png] x:\>EtcCompress 8192.png 1.etc /debug 1.png Loaded 8192.png Image 8192x8192, Texture 8192x8192 Compressed 4194304 blocks, elapsed 10988 ms, 381716 bps Saved 1.etc Texture RGB wPSNR = 42.796053, wSSIM_4x2 = 0.97524678 Saved 1.png x:\>EtcCompress 8192.png 1.etc /debug 2.png Loaded 8192.png Image 8192x8192, Texture 8192x8192 Loaded 1.etc Compressed 4194304 blocks, elapsed 6487 ms, 646570 bps Saved 1.etc Texture RGB wPSNR = 42.796053, wSSIM_4x2 = 0.97524678 Saved 2.png x:\>fc /b 1.png 2.png   1.png  2.png FC:    

このナヌティリティがモバむルグラフィックスを効率的か぀迅速に圧瞮するのに圹立぀こずを願っおいたす。

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


All Articles