前に少しだけunity触ったときになんとなくリニアワークフローが正しくないとおもいつつスルーしてたが、
今日改めて調べたらやはり注意すべき問題があることがわかった。バグかもしれないが運用で回避することが可能
通常のリニアワークフローではカラーテクスチャ等の見た目で作ったテクスチャはシェーダー内でデガンマされたリニア値で取り扱われる。
RGB等の数値の場合はもともとリニア値として使われるのが普通だが、Uniytyの場合はその数値もデガンマしている。
物理ベースの入力値を使う場合は注意が必要。
このあたりはマニュアルにも書いていなさそう。
というかUE4も含めて一般的なゲームエンジンでは入力値に関して物理ベースで正しく扱う気が無いように感じる。
というかUE4も含めて一般的なゲームエンジンでは入力値に関して物理ベースで正しく扱う気が無いように感じる。
UE4はテクスチャ以外の入力値はリニアとして処理されているがライト入力に関しては物理的な単位についてあまり明確な設定方法が記載されていない
リニアワークフローの設定方法
リニアワークフローの比較
ディフューズは0.5にし、ライトの強度を変えたものの比較
light_Intensity | 0.25 | 0.5 | 1 | 2 | 4 |
---|---|---|---|---|---|
unityのLWF | |||||
通常のLWF |
unityでは0.25では暗すぎ4.0では明るすぎるため、一見するとLWFができていないように感じるが、
そうではなくシェーディングに注目するとLWFはできていることがわかる。
そうではなくシェーディングに注目するとLWFはできていることがわかる。
こうなってしまうのはテクスチャ以外の入力値もデガンマされているからで、リニアワークフローに設定したら入力値が2.2乗されると考えてよい。
なのでライトのintensityが4.0の場合、実際は21.1のライトが当たっているということ
また、ライトのintensityが0.25の場合、実際は0.047のライトが当たっているということ
実際のライト強度 = pow(unityIntensity , 2.2)
例えばライトの明るさを16にしたい場合はunityでは
unityIntensity = pow(16 , 1/2.2) となり、3.53を入れればよいということになる
またマテリアルの数値にも同じことがいえる
上記のマテリアルのカラー値 128/255 で約0.5だが、実際の値は0.22となっている
この処理はsRGBテクスチャの場合にはデガンマ処理で行われるが数値に対しても行われているということ
実際のカラー値 = pow(rgb , 2.2)
例えば反射率0.18のグレーを入力したい場合はテクスチャと同様に0.46を入れればよいということ
デフォルトでテクスチャ以外の入力値に対してもデガンマされる処理は自分が知る限りUnityが初めて。(ほかにもあるかもしれないけど)
デフォルトでテクスチャ以外の入力値に対してもデガンマされる処理は自分が知る限りUnityが初めて。(ほかにもあるかもしれないけど)
unity内部のデガンマ処理がガンマ2.2なのかsRGBなのかはまだ調べていない。
調整例比較
ディフューズ0.1。平行光源の強度4.0の見え方が同じになるように調節した例。
理論値としては一番明るい部分は0.4となりガンマ2.2の補正が入るとしたらモニタ上では0.66 (168/255) となる
mayaはカラーマネジメントを有効にしてガンマ2.2を基準としたリニアワークフローに設定したもの。
また、もう一つのmayaの例は値の設定をディスプレイスペースにすることでunityと同じ感覚できることを検証したもの。
mayaはカラーマネジメントを有効にしてガンマ2.2を基準としたリニアワークフローに設定したもの。
また、もう一つのmayaの例は値の設定をディスプレイスペースにすることでunityと同じ感覚できることを検証したもの。
画像 | ランバート設定 | ライト設定RGB | |
---|---|---|---|
unityのLWF | RGB = (1,1,1) |
||
mayaのLWF | RGB = (1,1,1) | ||
mayaのLWF 別タイプ | (unityと同じ値) | ↓rgb側に含める強度はunitiyと同じ強度 |
0 件のコメント:
コメントを投稿