Search Unity

オンデマンドレンダリングでモバイルのパフォーマンスが向上するしくみ

, 2月 7, 2020

理由はさまざまですが、特にモバイルプラットフォームでは、プロジェクトを可能な限り高いフレームレートでレンダリングすることが必ずしも望ましいとは限りません。これまで Unity 開発者は、Unity のレンダリングスピードを抑えるために Application.targetFrameRate や Vsync Count を利用してきました。このアプローチは、レンダリングだけでなく Unity のさまざまな要素が実行される頻度にも影響します。新しいオンデマンドレンダリング API を使用すれば、レンダリングの頻度をプレイヤーループの頻度から切り離すことができます。

オンデマンドレンダリングとは

オンデマンドレンダリングでは、フレームのレンダリングをスキップしながらも、引き続きプレイヤーループの残りの部分を高い頻度で実行することができます。これは特にモバイルで強みを発揮します。レンダリングを回避することで、タッチイベントに対するアプリケーションの応答性を維持しつつ、パフォーマンスと省電力性を大幅に向上できます。

オンデマンドレンダリングを使う理由

フレームレートを下げる余地がある例をいくつか紹介します。

  1. メニュー(アプリケーションのエントリポイントや一時停止メニューなど):メニューは比較的シンプルなシーンになる傾向があり、そのような場合にはフルスピードでレンダリングする必要はありません。低めのフレームレートでメニューをレンダリングしたとしても、レンダリングされていないフレームの間に入力を受け付けることができるので、電力消費を低減して、CPU 周波数が抑制されるレベルまでデバイスの温度が上昇しないようにしつつ、滑らかな UI 操作を維持できます。
  2. ターンベースのゲーム(チェスなど):ターンベースのベームでは、ユーザーが次の動きを考えている間や他のユーザーの動きを待っている間に、アクティビティが減る時間が発生します。そのような時間にはフレームレートを下げることによって、不必要な電力の使用を防ぎ、バッテリー寿命を延ばすことができます。
  3. 静的コンテンツ:自動車のユーザーインターフェース(UI)など、大半の時間コンテンツが静的なアプリケーションでは、フレームレートを下げることができます。
  4. パフォーマンス管理:バッテリーをできるだけ長持ちさせたり、CPU スロットリングを回避したりするために電力使用量とデバイス温度を管理する場合(特に Adaptive Performance パッケージを利用している場合)は、レンダリングスピードを調整できます。
  5. 機械学習アプリケーションや AI アプリケーション:CPU がレンダリングに費やす作業量を減らすことで、アプリケーション本来の目的である高負荷処理のパフォーマンスが若干向上する可能性があります。

サポート対象

オンデマンドレンダリングは、サポートされているすべてのプラットフォーム(システム要件を参照)とレンダリング API(組み込みのレンダーパイプライン、ユニバーサルレンダーパイプライン、HD レンダーパイプライン)を備えた Unity 2019.3 で機能します。

オンデマンドレンダリングの使い方

オンデマンドレンダリング API は、名前空間 UnityEngine.Rendering のたった 3 つのプロパティーで構成されます。

OnDemandRendering.renderFrameInterval
これがもっとも重要なプロパティーです。これにより、レンダーフレーム間隔を取得または設定できます。これは、新しいフレームレートを定義するための Application.targetFrameRate または QualitySettings.vSyncCount の分割係数です。たとえば、Application.targetFrameRate を 60、OnDemandRendering.renderFrameInterval を 2 に設定すると、1 つおきのフレームだけがレンダリングされ、フレームレートは 30fps になります。

OnDemandRendering.effectiveFrameRate
このプロパティーを使うと、アプリケーションがレンダリングする際のフレームレートの概算値を得られます。この概算値は、OnDemandRendering.renderFrameInterval、Application.targetFrameRate、QualitySettings.vSyncCount の値とディスプレイのリフレッシュレートを使用して決定されます。ただし、あくまでも概算値であって、保証された値ではないことを忘れないでください。CPU がスクリプト、物理演算、ネットワークなどの他の処理に使用されてしまうと、アプリケーションのレンダリングスピードが低下する可能性があります。

OnDemandRendering.willThisFrameRender
このプロパティーでは、現在のフレームを画面にレンダリングされるかどうかを指定するだけです。レンダリングされないフレームは、高負荷の演算処理、アセットのロード、プレハブのスポーンなど、CPU 負荷の高いその他の処理に使用できます。

その他の知っておくべきポイント

  • フレームがすべてレンダリングされるわけではないとしても、イベントは通常のペースでスクリプトに送信されます。つまり、レンダリングされないフレームの間も入力を受け取る可能性があります。入力ラグの発生を避けるには、入力中は OnDemandRendering.renderFrameInterval = 1 を呼び出して、ボタンや操作などの応答性を保持することをお勧めします。
  • スクリプティング、物理演算、アニメーションなどに非常に高い負荷がかかっているにもかかわらず、レンダリングが行われていない状況では、オンデマンドレンダリングを使用するメリットがありません。その状況でオンデマンドレンダリングを使用しても、効果にはムラがあり、CPU や電力の使用量の低減はほとんど低減されない可能性があります。

オンデマンドレンダリングをメニューで使用して、入力がない間は 20fps でレンダリングされるようにする簡単な例を次に示します。

 

オンデマンドレンダリングをさまざまなシチュエーションで活用できることを紹介したサンプルプロジェクトは、こちらから入手できます。

オンデマンドレンダリングをご利用の皆さまへ

オンデマンドレンダリングを使用したご感想を、ぜひフォーラムでお聞かせください。Windows、macOS、WebGL、iOS、Android については、Unity Editor とスタンドアロンプレイヤーの両方でテスト済みですが、皆さまからのフィードバックをいつでもお待ちしております。

20 replies on “オンデマンドレンダリングでモバイルのパフォーマンスが向上するしくみ”

I think on-demand rendering is an excellent solution for achieving performance. My team has not tested yet, but thanks for the article!

“Where is it supported?” – Now it has become popular to use pre rendering (SPA), even in e-commerce projects. For example – https://firusas.com/, this is just a fashion website!
But even in e-commerce, they work on productivity, creating SPA.

Above all, aim to create a website that can balance aesthetics and performance on mobile, and achieve real conversion metrics. A collaborative, iterative performance optimization process will help you achieve this.

Right from the start of the project, encourage the internal team to work together under a mobile mindset by setting a strict performance budget. Build an understanding of the client and server-side factors that determine website performance on mobile. Then you can meet the goal set by implementing a mixture of the targeted optimization techniques I have described. Of course, there’s still a trade-off between having a striking design, high performance and security in some cases; a collaborative design and development team can decide what’s best for the business, checking with relevant project managers and stakeholders.

————————————————————-
Editor: https://mangazuki.site/

What are the differences between use of OnDemandRendering.renderFrameInterval 2 with Application.targetFrameRate 60 or directly use Application.targetFrameRate 30 manually? Also, if you recommend using OnDemandRendering.renderFrameInterval 1. Where do we gain performance? Thanks in advance!

1) Application.targetFrameRate will affect how often Update is called. OnDemandRendering will keep your Update cycle at the targeted rate, but rendering will only be performed once every n cycles.

2) targetFramerate is not intended to be manipulated frequently at runtime. Using it as an alternative to renderFrameInterval seems to function well enough on iOS, but can cause flickering on some Android devices.

I submitted a bug report regarding OnDemandRendering on Jan 28th and haven’t heard back. (1214921)

The issue seems to be that cameras rendering into render textures don’t get throttled correctly, and update their textures additively, affecting transparency.

Should I also start a forum thread to actually get attention?

Thank you so much for the great information that really help improve mobile performance.

I think that any resource can be used unethically. I had not considered this way of discussing a bad habit of on-demand rendering, but this sounds to me an easy case to be verified in stress tests.

I’m getting errors upon opening the example project.
“The name ‘RenderPipeline’ does not exist in the current context”

Thank you for adding this feature! This see this feature helping the application I am developing significantly.

Recently there were a lot of smartphones coming with advertised 90 & 120Hz screen refresh rates, which in reality are refreshing screen at 60Hz or less most of the time.
With 120Hz Samsung and iPhone phones coming this year, I foresee already an avalanche of mobile games coming soon with *120 screen refresh rate support!!!* ads labelled all over them, which in reality won’t reach even 60FPS most of the time. With developers saying “oh, you know, our game actually runs at 120FPS, we are just using on-demand rendering at 30FPS most of the time to save your battery, you know”. So this feature will come in handy for developers who want to cash in on the newest hype of high refresh screens, I suppose. Not so good for customers, who will be fooled again by yet another creative marketing.

I was hoping to see “Rendering layers”, still its a cool feature and absolutely will use it as soon as possible. Thanks Unity, Keep it up

What’s the difference between this and setting the target frame rate manually?

What about rendering in layers e.g. Onion Skybox’s so basic turning without moving can work with minimum rendering overhead?

Comments are closed.