[UE5]AutoScreenPercentage機能について

# 概要
UE5.0からAutoScreenPercentageという、ビューポートのサイズに応じて自動でスクリーン比率(ScreenPercentage)を変更する機能が導入されました。
UE5.0.0（正式版）からは、エディタのビューポートにその機能が導入されていて、ビューポートの広さに応じて自動的にスクリーン比率が下がるようになっています。

この記事では、AutoScreenPercentageの機能とデフォルトではどのような変化をするのかを書いていきます。

確認したエンジンのバージョンは、**UE5.0.0**です。

# AutoScreenPercentageのモード
AutoScreenPercentageはいくつかのモードがあります。
| 設定値 | モード | 概要 |
|:-:|:-:|:-:|
| 0 | Manual | 概ね従来のモード。<br>コンソールコマンドの**r.ScreenPercentage**の設定で指定した値が使われる |
| 1 | Based on display resolution | 表示解像度に依存して、自動的にスクリーン比率が制御される |
| 2 | Based on operating system's DPI scale | OS(Windows)のDPIスケールに依存して、自動的にスクリーン比率が制御される |

なお、この値はコンソールコマンドの**r.ScreenPercentage.Mode**によって制御されています。

:::note info
r.ScreenPercentage.Modeの説明文はまだ書き換わっていないため、説明文と実際の挙動が少し異なります。
:::

## エディタ時の挙動
また、エディタ時は以下の設定で上書きされます。
![AutoScreenPercentageEditor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431039/72c284b7-01b6-cc22-3997-3c2ac532e254.png)
このように、ビューポートのリアルタイムフラグの有無によって適用される値を変えることが可能です。

なお、どちらもコンソールコマンドで制御可能です。

+ リアルタイムエディタビューポートのデフォルトスクリーン比率モード
    + **r.Editor.Viewport.ScreenPercentageMode.RealTime**
+ 非リアルタイムエディタビューポートのデフォルトスクリーン比率モード
    + **r.Editor.Viewport.ScreenPercentageMode.NonRealTime**

:::note warn
デフォルトの値が上記画像の状態で、UE4依然と挙動が異なります。
スクリーン比率の値は以前は自分で操作しないと動きませんでしたが、UE5では違います。

「ビューポートを大きくしていたら、なんかぼやけてる気がする」というのは気のせいではなく、この機能が原因です。

また、スクリーン比率が自動調整されるため、思わぬ挙動が発覚することがありますので注意してください。
実際の例として、ポストプロセスマテリアルの計算にあった不具合が発覚しました。
:::

# スクリーン比率が自動計算されるタイミング
基本的に常に自動計算されていて、ウィンドウサイズの変更やコンテンツブラウザなどのドッキング/ドッキング解除など、ビューポートサイズが変わると新しい値が設定されるようになっています。
ただし手動でスクリーン比率に値を入れた場合は、そちらが優先されますので自動計算はされなくなります。

:::note info
スクリーン比率に以下の条件の値をいれると、自動計算が再開されます。

+ 25より小さい
+ 200より大きい
+ 自動計算された値と同じ値

自動計算された値が見えないので、特に3つ目の条件が分かりにくく **「手動で100を設定したつもりが自動に戻っていた」** なんてことが起きえます。
逆に自動に戻したい場合は、10などの25より小さい値を入れると良さそうです。
:::

# マニュアル(Manual)モード
前項で説明した通り、概ね従来のモードです。
コンソールコマンド **r.ScreenPercentage** で指定した値が使われます。
また、デフォルトは100.0(=100%)なのでUE4までと同じような感覚で使えると思います。
ただ、後述する **最大解像度/最小解像度** の影響は受けてしまいますので、UE4と全く同じではありません。

## エディタ時の挙動
![AutoScreenPercentageEditor3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431039/8dc221ed-735d-31c5-ef64-2b3576980942.png)
リアルタイムか非リアルタイムの設定を**Manual**にすると、マニュアルスクリーン比率の設定変更が可能なり、エディタ時はこの値が使われます。
この値もコンソールコマンドで制御可能です。
+ エディタビューポートに対してデフォルトで設定されるマニュアルスクリーン比率
    + **r.Editor.Viewport.ScreenPercentage**

# DPIスケール(Based on operating system's DPI scale)モード
説明が簡単なDPI Scaleモードを先に解説します。
![DPIScale.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431039/ede89882-6cac-6e7a-d9bc-1bc351c88a38.png)
上図のWindowsで設定するDPIスケールの逆数が自動的に設定されます。
この画像の例だと、DPIスケールは200%なので、スクリーン比率は 1/2.0 = 0.5 = 50(%) となり50に設定されます。

# 表示解像度(Based on display resolution)モード
ビューポートの表示解像度に依存して、自動的にスクリーン比率を計算するモードです。

## スクリーン比率の計算方法
様々なパラメータが関与しているため少々複雑ですが、デフォルトの値の時の変化をグラフにしました。
![AutoScreenPercentage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431039/aa2efa6e-5ab8-ede1-5ee2-db97dbae92f9.png)

このように、**基準縦解像度**が720以上になると徐々に下がっていき、4320で33.333%(1/3)まで下がります。

## 基準解像度について
この（スクリーン比率の計算方法）セクションで触れる解像度の値はすべて縦方向の解像度でアスペクト比は16:9が想定された値です。
そのため、前項の説明を補足すると、「基準縦解像度が720(1280ｘ720)以上になると徐々に下がっていき、4320(7680ｘ4320)で33.333%(1/3)まで下がります。」となります。

また、内部計算上は縦方向の解像度を基にアスペクト比が16:9と想定した総ピクセルを求めて比較などの計算を行っています。
特にエディタのビューポートはアスペクト比が一定ではないので、例えば1920ｘ640(=122880)といった横長のビューポートでも、総ピクセル数は1280ｘ720(=921600)を上回ります。
よって、スクリーン比率は下がり始めるので注意してください。

## [Rendering.AutoScreenPercentage]セクションの設定値
前出のグラフ内に書かれている

+ MinDisplayResolution（デフォルト値：720）
+ MinRenderingResolution（デフォルト値：720）
+ MidDisplayResolution（デフォルト値：1080）
+ MidRenderingResolution（デフォルト値：2160）
+ MaxDisplayResolution（デフォルト値：1440）
+ MaxRenderingResolution（デフォルト値：4320）

の各パラメータはBaseEngine.iniの[Rendering.AutoScreenPercentage]セクションに記載されています。
そのため、プロジェクト側のDefaultEngine.iniに記述すると設定を上書き可能です。

表示解像度がMinDisplayResolution～MidDisplayResolution、MinDisplayResolution～MaxDisplayResolutionの間で、RenderingResolution/DisplayResolutionの値を補間するようになっています。
デフォルト値を元に補間の状況を表で表すと以下のようになります。

|  | 基準表示解像度 | 総ピクセル数 | RenderingResolution / DisplayResolution | スクリーン比率 |
|:-:|:-:|:-:|:-:|:-:|
| Min | 720 | 921600 | 720/720 | 100% |
| ↑↓ | ↑↓ | ↑↓ | ↑↓ | ↑↓ |
| Mid | 2160 | 8294400 | 1080/2160 | 50% |
| ↑↓ | ↑↓ | ↑↓ | ↑↓ | ↑↓ |
| Max | 4320 | 33177600 | 1440/4320 | 33.33333% |

# 最小解像度と最大解像度
ここまでの説明で求められたスクリーン比率にさらに補正を書ける仕組みもあります。

最小解像度と最大解像度を指定して描画解像度がそれ以上、もしくはそれ以下にならないようにします。
どちらもコンソールコマンドで設定があり、

+ **r.ScreenPercentage.MinResolution**
+ **r.ScreenPercentage.MaxResolution**

で設定が可能です。デフォルトは0.0が指定されていて無効になっています。

## エディタ時の挙動
**r.ScreenPercentage.Mode** と同じで、これもエディタ時は別の値が使用されます。
![AutoScreenPercentageEditor2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431039/7fcd38df-9d2d-2f4d-b603-50cd52219b0b.png)
上図の値です。これらもコンソールコマンドで制御可能です

+ エディタビューポートに使用するデフォルトの最小レンダリング解像度
    + **r.Editor.Viewport.MinRenderingResolution**
+ エディタビューポートに使用するデフォルトの最小レンダリング解像度
    + **r.Editor.Viewport.MinRenderingResolution**

:::note warn
各モードで求められた値とは別で補正がかかります。そのため、マニュアルモードでスクリーン比率を指定していても、この補正は掛かります。
例えば、マニュアルモードでスクリーン比率を100と設定していても、デフォルトでは4K解像度(3840*2160)以上のビューポートを表示しようとすると、スクリーン比率は **下がっていきます**。
:::

# 手動設定
![ScreenPercentage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431039/0e15ecaa-d225-aa2f-2b7e-6622b6a35036.png)
各エディタビューポートのスクリーン比率を入力すると、手動設定モードになります。
ここまでで説明した自動調整は一切行われませんが、この状態はiniファイルなどで記録できないようなので、起動時から手動設定モードで固定というのは難しいようです。

::: note warn
少しややこしいですが、「スクリーン比率を手動入力した状態」（＝自動計算がされない状態）と「マニュアルモード」は別です。
前者は最小解像度と最大解像度が適用されず手動入力した値で固定されますが、後者は最小解像度と最大解像度が適用されるので、スクリーン比率は変化します。
:::

# あとがき
正直なところ、この機能を見つけた時は「（スクリーン比率を）勝手に書き換えられても…」と思いました。

しかし、この機能が追加された理由を推測すると、Naniteやレイトレなど表示解像度に依存して負荷が変わっていく仕組みが増えて、エディタ操作時のGPU負荷が無視できなくなってきたんじゃないかと思います。
ゲーム中ならそれぞれのPCスペックに応じて解像度や描画品質を選択しますが、開発中のエディタだと作業エリアの都合もありそう簡単に解像度を固定化できません。

とはいえ、勝手にスクリーン比率を下げられても、「なんとなくぼけてる気がするんだけど」と気づければいいほうで、たいていは気づかずに作業してしまいそうです。実際、私もポストエフェクトのバグが無ければたぶん気づいていませんでした。
特に絵作りをするアーティストにとっては有難迷惑な機能ですが、GPU負荷を一定にできるメリットもあり、どちらを取るかは各作業者の状況次第だと思います。チーム開発をしている場合は、デフォルトをどれにするかも悩ましいです。

開発中の見た目に影響するので結構重要な変更だと思うんですが、ドキュメントを探しても記述が見つかりませんでした。とりあえず、EpicGamesにはドキュメントの整備をお願いしたいです！:bow:

# 2023/08/31追記
https://qiita.com/marv_kurushimay/items/9722b22f9f279c362359

この記事を書いた後に分かったことを、補足として別記事に書きました。
高解像度スクショにも影響していたり、AutoScreenPercentageは意外と影響範囲が広そうです。