Open6

各社はHDR/WCGをどう説明しているのかメモ

okuokuokuoku

これyuniframeのドキュメントに書かないといけないんだよな。。

そもそもHDR/WCGとは

ゲームにせよなんにせよ、デジタルビデオシステムはR、G、Bの各色を0〜255の整数または適当な有理数で出力し、ディスプレイがそれらのデジタル値を光に変換することで成立している。このときのエンコーディングには標準規格がいくつか存在し、世代ごとに概ね:

と、その関連規格で定められている。世間のTVはこれらに従って企画されている...もっとも実際の製品としてのTVは、よりビビッドな色を出したりする都合これらをナイーブに実装しているわけではない。

ゲームのようなコンテンツに対してHDRとかWCGと言った場合は、基本的に少くとも現行規格のBt.709とかsRGBよりもダイナミックレンジが広く、色域(Color Gamut)が広いことを言う。具体的には:

  • HDR: sRGBの白(規格上80nit、実際の実装ではだいたい300nitくらい)よりも明い白(最低でも400nitくらい、Bt.2100の規格要求は1000nit、規格上限(変換関数のピーク)は10000nit)
  • WCG: Bt.2020の規定する各色の波長は人間にとってより赤く緑い(感覚のピークに近い)ため、これらの色をよりよく表現できるようになった。

じゃぁ今のシステムでも、RGBの 0〜255 の解釈を変えるだけで良いじゃんとなりそうだが、それだと階調が不足するため少くとも10bits以上の新しいエンコードを採用する必要がある。例えば、普及しているHDR10は、Bt.2100の規定するPQカーブ(物理的輝度とエンコードされた数値の対応を決めるOETF -- Optical-Electro Transfer Function)を採用していて、結果を10bitに量子化している。

(Deep Colorなら10bit以上あるじゃんという意見はあるかもしれないが ゲームシステムにおいては、Deep colorについては忘れて良い 。)

ゲームをHDR/WCG対応にするためには?

基本的には システムが対応しているフォーマットで絵を出力する ことが求められる。... PS5やXboxのようなゲームコンソールではsRGBゲームを自動的にHDRに拡張するし、HDR画像の表現方法にもいくつか存在するため、 HDMIで出ていくRGB信号を直接的にゲームがコーディングすることは原則的にできない (ie. テレビの実装自体がまちまちなので、調整一切なしのone-fits-allにはどうやってもならない)。

HDR/WCGな絵を出力するためには、

  • アセット
  • 空や太陽光などのシミュレーションアルゴリズム
  • 光収差などの非線形に動作するエフェクト
  • ブルームなどの演出 -- 光のあふれ出しなどで隠していたものが見えてしまう
  • 等々

を全てHDR/WCG用に作りなおす必要がある。FIXME: これCEDECか何かのプレゼンを引用すれば十分だよね多分

okuokuokuoku

Apple iOS/tvOS

AppleのシステムではEDR(Extended Dynamic Range)の概念を導入して既存のSDRを越えるディスプレイを透過的に扱えるようにしている。また、ColorSyncの本家だけあって基本的にアプリケーションは普及している任意のHDRフォーマットを供給してシステムに変換させることができる。

いわゆるPQやHLGエンコードは殆ど廃止されていて、アプリケーションはlinearで描画しシステムにディスプレイに合わせたカーブでのエンコードをさせることになる。 ... kCGColorSpaceDisplayP3_HLG は何故か生き残っている。

DisplayP3はAppleによる独自規格だが狙いはシンプルで、DCI P3の色空間を採用しつつsRGBと同様のエンコードを採用している。(MSのscRGBに近い立ち位置だが、sRGBの直接適用を捨てることで、極端な負値を不要にしている)

The Display P3 color space, created by Apple.
This color space uses the DCI P3 primaries, a D65 white point, and the sRGB transfer function.

またユーザがメタデータを供給してシステムにトーンマッピングを行わせることもできる。

iPhoneのようなディスプレイ上のSafariでは既にWCGなコンテンツを表示できるが、WebGLのような canvas で使えるかどうかは判然としない。

okuokuokuoku

Windows

わりと充実した解説。

Option 1. Use FP16 pixel format and scRGB color space
... In addition, if you're using Direct2D, Win2D, or Windows.UI.Composition, then this is the only supported combination for any swap chain or intermediate target that contains advanced color content.

元々scRGBはVistaが出るくらいの時期に提案されているので、現状のUHDTVにおけるHDR/WCGよりも歴史が古い。各色16bit floatさえ使えれば出力可能なため、原理的には伝統的なアプリケーションでもHDRに対応できる。

Option 2: Use UINT10/RGB10 pixel format and HDR10/BT.2100 color space

これは要は事前にPQエンコードすることを要求している。

ちなみに↑のドキュメントによるとWindowsのコンポジタはscRGBなので、コンポジタを通して描画する限りはコンテンツをBt.2020/PQで用意しても一旦変換が挟まってしまう。この節の図がわかりやすい

When advanced color is enabled, the DWM performs an explicit color conversion from the app visual content's colorspace to a canonical composition color space, which is scRGB.

Appleとは逆にBt.2020色空間でのリニア表現を用意していない。一般的なゲームは合成等の都合でリニア空間で中間バッファを構成することになるため、出力段でピクセルシェーダなり何なりで変換する必要がある。もっとも、通常のHDRレンダリングフローでは最終段にトーンマッピングすることになり、この変換は自然に導入できるので大きな問題にはならない。

okuokuokuoku

Android

HDR動画はアプリ側の描画ではなく、動画のデコードからディスプレイへの出力までシステムに任せるもの。WCGはDisplayP3とscRGB。

ケーパビリティの取得は Display.HdrCapabilities で可能なものの、これといった推奨は提供していないように見える。

okuokuokuoku

実際のところどうすべきなのか

CEDILでHDRを検索:

2021年現在では:

  • HLGは安全に無視できる(どこも前提にしなかった) -- YouTubeにアップロードする動画くらい
  • 未だに"SDRの方が良いシンドローム"はある (e.g. PS5は発売後にHDR変換を行わないSDRモードを追加した)
  • OpenGL ES3以上、Vulkanは前提にできる = レンダリングパイプラインはLinear前提にできる
  • アセットのオーサリングには結論がない。

2021年の現代的な"広色域"ディスプレイ/TVでも、DCI-P3(DisplayP3)程度の色再現性となる。このためBt.2020は色域が広すぎると言える。全体をDisplayP3前提で制作し、出力段で変換する(またはAppleやAndroidのようなP3ネイティブのシステムではそのまま出力する)のが良いような気がしている。