UnityでHDRレンダリングする際の設定項目と、その挙動を確認してみました。
HDRレンダリングに必要なもの
HDRレンダリングが通常のレンダリングと違う点は次の通りです。
以下、これらの設定方法と挙動を確認していきます。
HDRテクスチャを扱う
HDRテクスチャとはRGBに1以上の値を格納できるテクスチャです。
EXRやHDRといったHDR対応フォーマットのテクスチャをインポートすれば使えます。
ただしこのテクスチャを取り扱う場合は処理負荷が高く使用メモリも増えます。
そのため、擬似HDRテクスチャと呼ばれる、α値をうまく使ってLDRテクスチャにHDR情報を格納したテクスチャも使われるようです。
HDR光源を扱う
光源をHDR化するにはLightコンポーネントのIntensityを上げるだけです。 Lightの色にIntensityを乗算した値がシェーダに渡されます。
ただしリニア空間の場合はデガンマされるので注意が必要です。
浮動小数点バッファ
ブルームなどのポストエフェクトでHDR値を取り扱うには、
レンダーターゲットを浮動小数点バッファにしなければいけません。
これは以下の手順で設定できます。
ちなみにTier SettingsのHDR ModeではFP16の他にR11G11B10が選べます。
これは32ビットのバッファになるのでメモリにも処理負荷的にも優しくなります。
検証が必要ですが、諸々の条件が合うならこっちを使ったほうがよさそうです。
浮動小数点バッファの挙動を確認する
ちゃんとレンダーターゲットが変わっているか確認してみましょう。
まず、次のようなシェーダを書きます。
Shader "WriteHDRValue" { SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; float3 pos : TEXCOORD0; }; sampler2D _MainTex; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.pos = o.vertex.xyw; o.pos.y *= _ProjectionParams.x; return o; } fixed4 frag (v2f i) : SV_Target { half2 uv = i.pos.xy / i.pos.z * 0.5 + 0.5; return uv.x * 3.0f; } ENDCG } } }
ビューポート座標のxを3倍したものを出力しています。
レンダーターゲットが浮動小数点バッファになっている場合には0~3の値が書き込まれるはずです。
なっていない場合は1より大きい値が丸められて0~1が書き込まれます。
次にポストエフェクトのシェーダを書きます。
Shader "DecodeHDRPostEffect" { Properties{ _MainTex ("Texture", 2D) = "white" {} } SubShader { Cull Off ZTest Always ZWrite Off Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); col.rgb /= 3; return col; } ENDCG } } }
今度は入力色を3で割って出力しています。
レンダーターゲットが浮動小数点バッファになっていれば0〜1の値が得られます。
なっていない場合は上述の通り丸められた部分の色情報が失われて、0〜1/3の値が得られます。
1つ目のシェーダを適当なオブジェクトに適用し、
2つ目のシェーダをポストエフェクトに使うと結果は次のようになります。
これで浮動小数点バッファに書き込まれていることが確認できました。