rn.log

備忘録など

【ガンマ補正】sRGBテクスチャをRenderTextureに書き込むと表示が暗くなる話【Unity】

環境

Unity2020.2.0f1
Universal RP 10.2.2

はじめに

sRGBのテクスチャをCompute Shaderでサンプリングし、
計算結果をRenderTexture(sRGB)へコピーすると、表示がなぜか暗くなるという不可解な現象に遭遇しました。

f:id:r-ngtm:20210117111100p:plain
sRGBテクスチャをRenderTexture(sRGB)にコピーすると暗くなる

シェーダーにてsRGBテクスチャをサンプリングした色がリニア色空間であり、これをsRGBのテクスチャに書き込んだことによって発生する現象だと考えられます。

sRGBテクスチャから取得する色

sRGBテクスチャの色空間はガンマ色空間です。
sRGBテクスチャ(ガンマ色空間)をシェーダーでサンプリングする時、逆ガンマ補正された値(リニア色空間)がシェーダーへ流れてきます。

f:id:r-ngtm:20210117103352p:plain
sRGBテクスチャをsRGBレンダーテクスチャにコピーすると暗くなる

sRGBレンダーテクスチャにリニアカラーを書き込んでしまうと、Unity側でガンマ補正が行われなくなるため、表示結果が暗くなります。

sRGBカラーが逆ガンマ補正される理由について

sRGBテクスチャをサンプリングする時、逆ガンマ補正がなぜ入るのかをまとめてみたいと思います。

sRGBカラーはそのままモニターに表示される

ここで、sRGBテクスチャに 0.2, 0.3 という色が保存されていたとします。

これらをそのままモニターに表示した場合、0.2, 0.3 という色が表示されます。
モニターに送信される色は、ディスプレイ側で逆ガンマ補正がかかります。

f:id:r-ngtm:20210117122257p:plain
sRGBテクスチャカラーが画面に表示されるまで

sRGBカラーをそのまま使うと表示がおかしくなる

sRGBカラー 0.2, 0.3 という値をシェーダー内でそのまま足し算してしまうと、モニターには 1.134... という値が表示されてしまい、 0.2 + 0.3 = 0.5 という計算結果に一致しません。

f:id:r-ngtm:20210117122956p:plain
sRGBテクスチャカラーをそのまま足すと結果がおかしくなる

sRGBカラーを逆ガンマ補正すると表示が正しくなる

sRGBカラー を最初に逆ガンマ補正してからシェーダーにて足し算を行い、
モニターに送信する前にガンマ補正をかけてやると、モニター上には 0.5 という色が表示されます。

sRGBカラーの  0.2 + 0.3 = 0.5 という計算結果と、モニター上の表示0.5 が一致するのでこれは都合が良い結果となります。

f:id:r-ngtm:20210117123053p:plain
sRGBカラーを逆ガンマ補正してから計算に使った場合

sRGBカラーの逆ガンマ補正はUnityが自動でやってくれるようです。

f:id:r-ngtm:20210117124325p:plain
sRGBのチェックを入れると、シェーダー利用時に逆ガンマ補正がかかるようになります