コンテンツにスキップ

負荷を抑える

最初に、重さの種類を見分ける

Section titled “最初に、重さの種類を見分ける”

このページは、オーバーレイを出すと VR 全体が重くなる、またはオーバーレイの動きだけがカクつくときに、負荷の原因を見つけて減らす手順です。VR の中で動くので、オーバーレイの負荷は、VR 体験全体の快適さに響きます。

最初に、重さの種類を見分けます。同じ VR アプリ・同じ操作で、オーバーレイを起動した状態と終了した状態を比べてください。

観点 当てはまるとき
オーバーレイを終了しても、VR が重い VRChat や GPU のドライバーなど、FloatSoda の外に原因がある。このページでは直せない
オーバーレイを出したときだけ、VR が重い、またはオーバーレイの動きだけがカクつく FloatSoda のアプリ側で調整できる。手順 1 へ進む

調整できる箇所は 3 つです。フレームレートの設定、再描画の範囲、更新の頻度です。

変える前の値を控えます。値を控えておくと、調整のたびに、効いたかどうかを数字で比べられます。

測る値は、フレームレートと GPU の使用率の2つです。FloatSoda に計測の機能はないので、SteamVR と Windows の表示を使います。SteamVR でフレームの時間を表示する方法は、Valve の SteamVR の資料にあります。

毎回同じ操作(たとえば、ダッシュボードを開いて 30 秒眺める)で測ってください。

できた? 変える前の値が手元にある。

手順2: フレームレートの設定を下げる

Section titled “手順2: フレームレートの設定を下げる”

目標のフレームレートは FloatSodaOptions.TargetFrameRate で決まり、既定は 60 です。メインループと描画ループの両方がこの値に合わせて動くので、下げると処理の回数が減ります。

builder.Services.AddFloatSoda(new FloatSodaOptions
{
TargetFrameRate = 30,
});

1 以上の整数を指定します。0 以下にすると、起動時に ArgumentOutOfRangeException になります。値を下げると、アニメーションの描き換え回数も減るので、動きは粗くなります。

値を下げて起動し、手順 1 と同じ操作で測り直します。

できた? 値の変化が数字で見える。

FloatSoda は、変わった部分だけを作り直し、そのレイアウトと描画をやり直します。変更のないフレームでは、レイアウトと描画を行いません。範囲を絞ると、やり直す処理が減ります。絞る方法は 2 つあります。

1 つ目は、RepaintBoundary で囲むことです。RepaintBoundary で囲んだ子は、独立した描画の層に分けられます。囲んだ中だけが変わっても、外側は描き直されません。省けるのは描画だけで、ウィジェットの作り直しとレイアウトは省けません。

new Column
{
Children =
{
new Text("見出し(変わらない)"),
new RepaintBoundary
{
Child = new CounterWidget(), // 頻繁に変わる部分
},
},
}

2 つ目は、SetState() を呼ぶ State を小さく分けることです。SetState() は、その State を持つウィジェットの下を作り直します。頻繁に変わる値は、その値を表示する小さなウィジェットの State に持たせると、作り直す範囲が狭くなります。画面全体のルートで SetState() を呼ぶと、画面全体が作り直されます。仕組みは 状態と作り直し にあります。

頻繁に変わる部分を囲み、測り直します。

できた? 測り直した値が下がり、見た目と操作感が変わっていない。

更新の頻度を減らす方法は 3 つあります。該当するものを直します。

  • タイマーで SetState() を呼んでいる場合は、必要な表示頻度に合わせて、更新の間隔を長くすることが望ましい
  • 不透明度を動かすために SetState() を毎フレーム呼んでいる場合は、FadeTransition に替えること
  • 固定の SizedBox などで足りる場合は、IntrinsicWidth と IntrinsicHeight を避けることが望ましい

理由は次のとおりです。画面に見える変化が必要な頻度より短い間隔で更新していると、見えない更新に処理を使います。FadeTransition は、アニメーションの値を再描画だけで反映するので、1 フレームごとの SetState() が要りません。IntrinsicWidth と IntrinsicHeight は子の自然な大きさを調べるためにコストが高く、多用すると負荷が上がります。

あわせて、次の 2 点も負荷に関わります。

  • 画面のピクセル数が大きいほど、描画する面積が増えます。ピクセル数は Size で決まり(省略するとレイアウト結果の大きさになります)、VR 内の実寸は Dpm で決まります。DashboardWindow では Dpm が表示サイズに影響しない場合があります(レイアウトの考え方)。必要以上に大きな画面にしないことが、負荷を抑える手段になります。
  • 複数のウィンドウを同時に出すと、ウィンドウごとにレイアウトと描画の処理が行われます。使っていないウィンドウは作らないでください。

できた? 測り直した値が下がる。

手順 1 で控えた値と、調整後の値を、同じ操作で測って比べます。調整は 1 つずつ行い、そのたびに測ります。フレームレートが上がった、または GPU の使用率が下がり、動きと操作感が許容できれば、調整は効いています。効果がない、または操作感が悪化した変更は、元に戻します。

直らないときの行き先は、ガイドの docs で見つからないとき にあります。聞くときは、次の情報を添えてください。

  • 測った値(調整前と調整後、測った道具)
  • ウィンドウの数と種類
  • 画面の大きさ(Size と Dpm)
  • TargetFrameRate の値