北条ゲームズ Hojo Games

錦の北条の開発ブログ

スポンサーサイト 

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

【コラム】Unityキセキの世代の皆さんが(モバイルの)半透明のパフォーマンスについて知るべき事 

生存報告を兼ねた簡単な社会貢献記事です まあ僕もUnity奇跡の世代ですが

自分の認識レベルと勢いで適当なことを書いていきます 一定初心者の役に立つと信じての記載ですがまったく専門でないので間違ってたら殴ってください


では本題
曖昧な話でモバイルだと半透明遅い!みたいな 話ありますよね よく聞きますよね 聞きませんか?いや聞く気がする お願い 聞いたことあってほしい
で、皆さん意味もなく避けてませんか
あの辺りって全く単純な話のようでそうでなくて
というか、避けるべきものとそうでないものがあります いや、まあ半透明なんか避けられるなら全部パフォーマンス的には避けた方がいいかもしれないんですけども 無理ですよね 普通に表現を優先してください

まず、iPhone系とAndroidの一部で重いと言われる半透明は"CUTOUT"です すみません、cutoutって半透明ですらないですね でも、モバイルで半透明って、普通だもん 多分普通程度に重いだけなんだもん! ですから重いとか親の仇みたいに言われてるのはCutoutについてなんでしょう
この辺の理由は一部グラフィクスのアーキテクチャで採用されている方のTBDRというものがあり、画面全体をいくつかのタイルに区切って、それらついて先に最低限の描画をやってそれぞれの中の前後関係を高速で調べピクセルシェーダ(重い)の実行を最低限にするのですが、本来テクスチャアクセスが必要ないのに、Cutoutがあるとやる羽目になり、みたいな話っぽいです
ちなみにPSVitaもPowerVRを採用しているのでCutoutに弱い特性を持ってるはずです

2017y03m13d_155658822.png ↑図:インスタンシングで高速描画されるCUTOUTな草
補足なのですが、CUTOUTは描画or死のタイプの透明系(ではないが)なので、普通の半透明(Transparent)と異なり深度情報※を適切に用意できますし前後関係きちんとやれますから、普通のハードウェアではもちろんのこと、適宜利用してください

※ 深度:前後関係の数値情報 もっともカメラから近いものまでの距離がピクセルごとに数値として保存されていて、そのおかげで一般的な描画において前後関係が整合性を帯びる 
この情報を用いてピクセルを描画するかどうかを決めることをZテストといい、基本的に何かの後ろにあると判定された位置のオブジェクトのピクセルシェーダ(フラグメントシェーダ)は実行されずに済む

で、そういったモバイルの一部の端末でもTransparentは相応のパフォーマンスです。後から描画するだけなので普通通りです
まあでも、本当はpowerVRとかのtbdrってきちんとした一枚の深度情報出力すらしないんですかね もししないで済んでるなら、transparentが一つでもあったらその描画のためにわざわざ出力してる可能性もありますね それならそこにオーバーヘッドあるかもしれない(知らんけど)


次に普通の半透明(Transparent)についても書くんですが
これはどんなんでも一定重いです!
モバイルであることさえ関係ない まあモバイルはパワーが低いので問題になりやすい傾向はあるんですが……
とにかく、同じ複雑度のシェーダで一般的なシーンに半透明と不透明物体があった場合は基本半透明が重くなりやすいです

2017y03m20d_233139575.png↑図:超一か所に大量描画されているパーティクル(重い)

理由は重ね書きのリスクが高い!って話が一つだと思います 密接した箇所に沢山出すと超重ね掛け!不透明なら案外深度テスト通らずにうまいことシェーダが走らずに済むところも、半透明はめっちゃ重ね書きされるリスクがあります
あと普通に不透明なものが描画され終わった後に描画してるという事実もあるんですよ たとえたった一枚しか半透明テクスチャが上にのってなかったからって、その分は確実に余計に描画してるんですね(ちなみに、余計な描画の観点だけでなく単純にこの描画の命令の”回数”もパフォーマンスには直結します 色々バッチングなど現実ではやってもらえるはずですが、面積*描画回数とはならずもうちょっとオーバーヘッドがある筈です とはいえ、そこまで気にする必要は一切無いんですが)
gpuがピクセル埋める能力みたいなもののことをフィルレート(埋める率)とか言いますが、まあ食いますよね 描くのは重いんです いいですか、これ重要です 描くのは重い!
もちろんピクセルシェーダを軽くする努力などすれば緩和はされます。一般に重ねて描画されやすいエフェクト系はピクセルシェーダを軽く出来ると良いでしょう。
グラフィクスパイプラインは本当は色々な賢しいことをやって書かないで済むよう頑張ってるっぽいですので、問答無用で描画させてくる奴らは本当に横柄でヤベエすねぇ~~って感じで見れればいいです

定性的な話ですが、特にモバイルについてもし実際にフレームレートが安定しないとか、目に見えて問題になったらこの辺りを思い浮かべられるといいんじゃないかと思います 結局実際に重くならない限りは問題は問題では無いので、軽ーく感覚的に押さえておくといいですね

知ってるとよさげな対策
半透明なエフェクトなどだけそもそも描く領域を小さくしちゃいます
バイリニアフィルタなんかを後で適応してあげれば案外なんとかなる理論
やったことないが、深度マップを通常のカメラからもらえるはずなので前後関係維持しつつUnityでもできそう カメラ出力の解像度簡単に下げるにはrendertextureを使うことになると思うので、まあまあなピクセルシェーダ負荷で超大量に重ね描画ある!みたいシーンだったらほぼ確実に効果ありますが、その辺のオーバーヘッドを計測しつつ、やってみるならやってみるといいと思います

・ポリゴンで切り抜く
CUTOUTやるくらいなら、或いは半透明で大量描画するくらいなら、状況によっては普通にポリゴンとして切り抜いてる方が早いこともある気がします
まあ諸々の複雑度次第でしょう 計測しつつやってみてください

以上です 上は超ざっくりした話ですが、とっかかりにして色々調べてくれればいいです
僕も最初全く訳分かんなかったんで


Comment

Add your comment

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。