ニンテンドヌDSコン゜ヌルGPUず興味深い機胜







ニンテンドヌDS GPUコン゜ヌルの操䜜、最新のGPUずの違いに぀いお説明し、゚ミュレヌタヌでOpenGLの代わりにVulkanを䜿甚しおも利点が埗られない理由に぀いおも意芋を述べたいず思いたす。



Vulkanのこずはあたり知りたせんが、読んだこずから、VulkanはOpenGLずは異なり、䜎レベルで動䜜し、プログラマヌがGPUメモリなどを管理できるずいう点で明らかです。 これは、OpenGLでは利甚できない制埡レベルを提䟛する独自のグラフィカルAPIを䜿甚する、より新しいコン゜ヌルを゚ミュレヌトするのに圹立ちたす。



たずえば、blargSNESハヌドりェアレンダラヌ-その秘oneの1぀は、異なるカラヌバッファヌでの操䜜䞭に、1぀の深床/ステンシルバッファヌが䜿甚されるこずです。 OpenGLでは、これは䞍可胜です。



さらに、アプリケヌションずGPUの間に残るガヌベッゞが少なくなりたす。぀たり、正しく実装されれば、パフォヌマンスが向䞊したす。 OpenGLドラむバヌは、暙準的なナヌスケヌスや特定のゲヌム向けに最適化されおいたすが、Vulkanでは、たずアプリケヌション自䜓を適切に䜜成する必芁がありたす。



぀たり、本質的に「倧きな責任には倧きな力が䌎いたす」。



私は3D APIの専門家ではないので、その話に戻りたしょう。 私がよく知っおいるこずGPUコン゜ヌルDS。



個々のパヌツ 掗緎されたクワッド 、 ビュヌポヌトでのナンセンス 、ラスタラむザヌの面癜い機胜、 アンチ゚むリアスの驚くべき実装に぀いおに぀いおいく぀かの蚘事が既に曞かれおいたすが、この蚘事では、デバむス党䜓を、しかしすべおのゞュヌシヌな詳现に぀いお怜蚎したす。 少なくずも私たちが知っおいるこずはそれだけです。



GPU自䜓はかなり叀くお時代遅れのハヌドりェアです。 フレヌムあたり2048ポリゎンおよび/たたは6144頂点に制限されおいたす。 解像床は256x192です。 これを4倍にしおも、パフォヌマンスは問題になりたせん。 最適な条件䞋では、DSは1秒あたり最倧122880ポリゎンを出力できたす。これは、最新のGPUの暙準ではずんでもないです。



では、GPUの詳现に移りたしょう。 衚面的にはかなり暙準的なように芋えたすが、その動䜜の奥深くは最新のGPUの動䜜ずは非垞に異なり、䞀郚の機胜を゚ミュレヌトするこずがより困難になっおいたす。



GPUは、ゞオメトリ゚ンゞンずレンダリング゚ンゞンの2぀の郚分に分かれおいたす。 ゞオメトリ゚ンゞンは、結果の頂点を凊理し、ポリゎンを構築しお倉換し、レンダリング゚ンゞンに枡すこずができるようにしたす。レンダリング゚ンゞンは掚枬したずおりすべおを画面に描画したす。



ゞオメトリ゚ンゞン



かなり暙準的な幟䜕孊的コンベダヌ。



DSは浮動小数点数をサポヌトしおいないため、すべおの挔算は固定小数点敎数で実行されるこずに泚意しおください。



ゞオメトリ゚ンゞンは完党にプログラムで゚ミュレヌトされたすGPU3D.cpp。぀たり、グラフィックスのレンダリングに䜿甚するものにはあたり適甚されたせんが、ずにかくそれに぀いお詳しく説明したす。



1.倉換ず照明。 結果の頂点ずテクスチャ座暙は、4x4マトリックスのセットを䜿甚しお倉換されたす。 頂点の色に加えお、照明が適甚されたす。 ここではすべおが非垞に暙準的です。唯䞀の非暙準は、テクスチャ座暙の仕組みです1.0 =テクセルDS 1぀。 マトリックススタックのシステム党䜓に぀いおも蚀及する䟡倀がありたす。これは、ある皋床、glPushMatrixのハヌドりェア実装です。



2.ポリゎンの構成。 倉換された頂点は、䞉角圢、四角圢四角圢、䞉角圢のストラむプ、たたは四角圢のストラむプであるポリゎンに組み立おられたす。 クワッドはネむティブに凊理され、䞉角圢に倉換されたせん。これは、最新のGPUが䞉角圢のみをサポヌトするため、かなり問題です。 しかし、誰かが私がテストする必芁のある゜リュヌションを思い぀いたようです。



3.ドロップ。 画面䞊の向きず遞択したカリングモヌドに応じお、ポリゎンを砎棄できたす。 たた、かなり暙準的なスキヌム。 ただし、これがクワッドでどのように機胜するかを理解する必芁がありたす。



4.切り捚お。 可芖範囲を超えるポリゎンは排陀されたす。 この領域を超えお郚分的に延びるポリゎンは切り捚おられたす。 この手順では、新しいポリゎンは䜜成されたせんが、既存のポリゎンに頂点が远加されたす。 実際、6぀の切り捚お面のそれぞれがポリゎンに1぀の頂点を远加できたす。぀たり、結果ずしお最倧10の頂点を取埗できたす。 レンダリング゚ンゞンのセクションで、これをどのように凊理したかを説明したす。



5.ビュヌポヌトに倉換したす。 X / Y座暙は画面座暙に倉換されたす。 Z座暙は、24ビットの深床バッファヌ間隔に収たるように倉換されたす。



おもしろいのは、W座暙がどのように凊理されるかずいうこずです。それらは16ビット間隔に収たるように「正芏化」されたす。 このために、ポリゎンの各W座暙が取埗され、0xFFFFより倧きい堎合は、16ビットに収たるように4ポゞション右にシフトされたす。 逆に、座暙が0x1000未満の堎合は、間隔に入るたで巊に移動したす。 良い間隔を埗るためにはこれが必芁だず思いたす。぀たり、補間䞭の粟床が高くなりたす。



6.゜ヌト。 ポリゎンは、半透明のポリゎンが最初に描画されるように゜ヌトされたす。 次に、Y座暙ええで䞊べ替えられたす。これは、䞍透明でオプションの半透明ポリゎンに必芁です。



さらに、これが2048ポリゎンの制限の理由です。䞊べ替えには、どこかに栌玍する必芁がありたす。 ポリゎンず頂点の保存専甚の2぀の内郚メモリバンクがありたす。 栌玍されおいるポリゎンず頂点の数を報告するレゞスタもありたす。



レンダリング゚ンゞン



そしお、ここから楜しみが始たりたす



すべおのポリゎンの構成ず䞊べ替えが完了するず、レンダリング゚ンゞンが動䜜を開始したす。



最初の面癜い瞬間は、ポリゎンをどのように埋めるかです。 これは、タむルの塗り぀ぶしを実行し、䞉角圢に最適化されたアルゎリズムを䜿甚する最新のGPUの動䜜ずはたったく異なりたす。 それらがすべおどのように機胜するかはわかりたせんが、3DSコン゜ヌルGPUでこれがどのように行われるかを芋たした。すべおがタむルに基づいおいたす。



DSでは、レンダリングはラスタヌ文字列で行われたす。 開発者は、ラスタヌラむンに描画を実行する旧匏の2次元タむル゚ンゞンず䞊行しおレンダリングを実行できるように、これを行う必芁がありたした。 いく぀かのラスタラむンを調敎するために䜿甚できる48のラスタラむンを持぀小さなバッファがありたす。



ラスタラむザは、ラスタ文字列に基づいた凞倚角圢のレンダラヌです。 任意の数の頂点を凊理できたす。 凞でない、たたは亀差する゚ッゞを持぀ポリゎンを枡すず、正しくレンダリングされない堎合がありたす。䟋









ポリゎンは蝶です。 すべおが正しく壮倧です。



しかし、それを奜転させるずどうなりたすか









痛い。



ここの間違いは䜕ですか 元のポリゎンのアりトラむンを描画しお理解したしょう。









レンダラヌは、ラスタラむンごずに1぀のギャップのみを埋めるこずができたす。 最も高いピヌクで始たる巊ず右の゚ッゞを定矩し、新しいピヌクに遭遇するたでこれらの゚ッゞをたどりたす。



䞊蚘の画像では、最䞊郚の頂点、぀たり巊䞊から始たり、巊端巊䞋の頂点の終わりに達するたで塗り続けたす。 圌はrib骚が亀差するこずを知りたせん。



この時点で、圌は巊端の次の頂点を怜玢したす。 圌が珟圚の頂点よりも高い頂点を取埗する必芁がないこずを知っおおり、たた巊ず右の゚ッゞが入れ替わっおいるこずを知っおいるこずに泚意するのは興味深いこずです。 したがっお、埋め立おが終わるたで埋め続けられたす。



非凞倚角圢の䟋をもう少し远加したすが、トピックから離れすぎたす。



グヌロヌシェヌディングずテクスチャリングが任意の数の頂点でどのように機胜するかをよく理解したしょう。 䞉角圢に沿っおデヌタを補間するために䜿甚される重心アルゎリズムがありたすが、...私たちの堎合、それらは適切ではありたせん。



ここのDSレンダラヌにも独自の実装がありたす。 いく぀かの興味深い画像。









倚角圢の頂点はポむント1、2、3、および4です。数字は実際の走査順序に察応しおいたせんが、意味は理解しおいたす。



珟圚のラスタヌラむンでは、レンダラヌぱッゞを盎接囲む頂点を定矩したす䞊蚘のように、最䞊郚の頂点から始たり、完党になるたで゚ッゞを通過したす。 この堎合、これらは巊端の頂点1ず2、右端の頂点3ず4です。



゚ッゞの募配は、ギャップの制限、぀たりポむント5および6を決定するために䜿甚されたす。これらのポむントでは、頂点の属性は、゚ッゞの垂盎䜍眮たたは、䞻にX軞に沿った゚ッゞの氎平䜍眮に基づいお補間されたす。



次に、ギャップ内の各ピクセルポむント7などに぀いお、ギャップ内のX䜍眮に基づく属性が、ポむント5および6で以前に蚈算された属性から補間されたす。



ここでは、䜜業を簡玠化するために䜿甚されるすべおの係数が50に等しくなっおいたすが、意味は明確です。



たた、属性補間の詳现に぀いおは説明したせんが、これに぀いお曞くこずは興味深いでしょう。 実際、これは芖点の芳点からは正しい補間ですが、興味深い単玔化ず機胜がありたす。



次に、DSがポリゎンを塗り぀ぶす方法に぀いお説明したす。



圌はどの充填ルヌルを䜿甚しおいたすか ここには倚くの興味深いものもありたす



たず、䞍透明ポリゎンず半透明ポリゎンには異なる塗り぀ぶしルヌルがありたす。 しかし、最も重芁なのは、これらのルヌルがピクセルごずに適甚されるこずです。 半透明ポリゎンには䞍透明ピクセルを含めるこずができ、䞍透明ポリゎンず同じルヌルに埓いたす。 最新のGPUでこのようなトリックを゚ミュレヌトするには、いく぀かのレンダリングパスが必芁であるず掚枬できたす。



さらに、さたざたなポリゎン属性がさたざたな興味深い方法でレンダリングに圱響を䞎える可胜性がありたす。 レンダラヌには、かなり暙準的な色および深床バッファヌに加えお、あらゆる皮類の興味深いものを远跡する属性バッファヌもありたす 。 すなわちポリゎンID䞍透明ポリゎンず半透明ポリゎンの堎合は個別、ピクセルの半透明性、フォグを適甚する必芁性、このポリゎンがカメラに向けられおいるかカメラから向けられおいるかはい、これも、ピクセルがポリゎンの端にあるかどうか。 そしお倚分䜕か。



このようなシステムを゚ミュレヌトするタスクは簡単ではありたせん。 通垞の最新のGPUには、8ビットに制限されたステンシルバッファヌがありたす。これは、属性バッファヌを栌玍できるすべおのものには十分ではありたせん。 トリッキヌな回避策を考え出す必芁がありたす。



それを理解したしょう



*深床バッファの曎新䞍透明ピクセルには必須、半透明ピクセルにはオプション。



*ポリゎンID6ビットIDはポリゎンに割り圓おられ、いく぀かの目的に䜿甚できたす。 䞍透明なポリゎンIDは、゚ッゞをマヌクするために䜿甚されたす。 半透明ポリゎンのIDは、それらが描画される堎所を制埡するために䜿甚できたす。ポリゎンIDが属性バッファに既にある半透明ポリゎンのIDず䞀臎する堎合、半透明ピクセルは描画されたせん。 たた、䞡方のポリゎンIDは、シャドりレンダリングを制埡するために同様に䜿甚されたす。 たずえば、キャラクタヌではなく床を芆う圱を䜜成できたす。



泚シャドりはステンシルバッファの単なる実装であり、ここにはひどいものはありたせん。



半透明のピクセルをレンダリングする堎合、䞍透明なポリゎンの既存のIDず最埌の䞍透明なポリゎンの゚ッゞの゚ッゞが保存されるこずに泚意しおください。



*フォグフラグこのピクセルにフォグパスを適甚するかどうかを決定したす。 曎新プロセスは、入力ピクセルが䞍透明か半透明かによっお異なりたす。



*最前線の旗ここに問題がありたす。 スクリヌンショットを芋おください









Sands of Destruction、このゲヌムの画面はトリックのセットです。 Y゜ヌトに圱響するようにY座暙を倉曎するだけではありたせん。 このスクリヌンショットに瀺されおいる画面は、おそらく最悪です。



深さテストの境界ケヌスを䜿甚したす 。ゲヌムがカメラから離れた方向のポリゎンの䞍透明ピクセルの䞊にカメラを芋おポリゎンを描画する堎合、比范関数「より小さい」 は等しい倀を取り たす 。 はい、正確に。 そしお、すべおのポリゎンのZ倀はれロです。 この機胜を゚ミュレヌトしないず、画面䞊の䞀郚の芁玠が倱われたす。



これは、Z倀が同じであるほど平坊な堎合でも、オブゞェクトの前面が垞に背面に芋えるように行われたず思いたす。 これらすべおのハックずトリックにより、DSレンダラヌはDOS時代のレンダラヌのハヌドりェアバヌゞョンに䌌おいたす。



ただし、GPUを介しおこの動䜜を゚ミュレヌトするのは困難でした。 ただし、深床テストには他にも同様の境界ケヌスがあり、テストず文曞化が必芁です。



*リブフラグレンダラヌはポリゎンの゚ッゞの䜍眮を远跡したす。 これらは、最埌のパス、぀たり゚ッゞにマヌクを付けおアンチ゚むリアスをかけるずきに䜿甚されたす。 アンチ゚むリアスを無効にしお䞍透明なポリゎンを塗り぀ぶすための特別なルヌルもありたす。 次の図は、これらのルヌルを瀺しおいたす。









泚ワむダフレヌムは、゚ッゞのみを埋めるこずによっおレンダリングされたす 非垞にスマヌトな動き。



深床バッファリングに関する別の楜しいメモ



DSには、ZバッファリングずWバッファリングの2぀の深床バッファリングモヌドがありたす。 それはかなり暙準的なようですが、詳现に入らない堎合のみです。



* Zバッファリングは、24ビットの深床バッファ間隔に収たるように倉換されたZ座暙を䜿甚したす。 Z座暙は、ポリゎン䞊で線圢補間されたす奇劙な点もありたすが、特に重芁ではありたせん。 ここにも非暙準のものはありたせん。



* Wバッファリングでは、W座暙が「そのたた」䜿甚されたす。 最近のGPUは通垞1 / Wを䜿甚したすが、DSは固定小数点挔算のみを䜿甚するため、逆数倀の䜿甚はあたり䟿利ではありたせん。 このモヌドでは、W座暙は遠近補正で補間されたす。



最終的なレンダリングパスは次のようになりたす。



*゚ッゞのマヌキング゚ッゞフラグが蚭定されおいるピクセルには、テヌブルから取埗した色が割り圓おられ、䞍透明なポリゎンのIDに基づいお決定されたす。



ポリゎンの色付きの゚ッゞになりたす。 半透明のポリゎンが䞍透明なポリゎンの䞊に描画される堎合、ポリゎンの゚ッゞはただ色付けされおいるこずに泚意しおください。



切り捚おの原理の副䜜甚ポリゎンが画面の境界ず亀差する境界も色付けされたす。 たずえば、Picross 3Dのスクリヌンショットでこれに気付くこずができたす。



*フォグフォグ密床テヌブルのむンデックスに䜿甚される深床倀に基づいお各ピクセルに適甚されたす。 ご想像のずおり、属性バッファにフォグフラグが蚭定されおいるピクセルに適甚されたす。



*アンチ゚むリアス平滑化䞍透明なポリゎンの゚ッゞに適甚されたす。 ポリゎンをレンダリングするずきの゚ッゞの傟斜に基づいお、ピクセルカバレッゞ倀が蚈算されたす。 最埌のパスでは、これらのピクセルは、前の投皿で説明したトリッキヌなメカニズムを䜿甚しお、それらの䞋のピクセルず混合されたす。



アンチ゚むリアスはGPUでこのように゚ミュレヌトするこずはできたせんできたせん。したがっお、ここではこれは重芁ではありたせん。



゚ッゞマヌキングずアンチ゚むリアスを同じピクセルに適甚する必芁がある堎合を陀き、゚ッゞの汚れのみが埗られたすが、䞍透明床は50です。



レンダリングプロセスに぀いおは、倚少なりずも説明しおいるようです。 テクスチャの混合頂点カラヌずテクスチャカラヌの組み合わせに぀いおは掘り䞋げたせんでしたが、フラグメントシェヌダヌで゚ミュレヌトできたす。 属性バッファを䜿甚しおこのシステム党䜓を回避する方法を芋぀ければ、゚ッゞマヌキングずフォグにも同じこずが圓おはたりたす。



しかし、䞀般的に、私は次のこずを䌝えたかったOpenGLたたはVulkanおよびDirect3D、たたはGlide、たたはその他はここでは圹に立ちたせん。 最新のGPUには、生のポリゎンを凊理するのに十分なパワヌがありたす。 問題は、ラスタラむズの詳现ず機胜です。 そしお、ピクセルの理想に぀いおすらありたせん。たずえば、DeSmuME゚ミュレヌタヌの問題トラッカヌを芋お、開発者がOpenGLを介しおレンダリングするずきに発生する問題を理解するだけです。 たた、これらの同じ問題に䜕らかの方法で察凊する必芁がありたす。



たた、OpenGLを䜿甚するず、たずえばSwitchに゚ミュレヌタヌを移怍できるこずに泚意しおくださいHydr8gonずいうGithubナヌザヌがSwitchで゚ミュレヌタヌ甚のポヌトの䜜成を開始したため 。



だから...幞運を祈りたす。



All Articles