Renderingこの記事では疑似HDRレンダリングを実装します。疑似HDRとは、浮動小数点バッファを使わずに実装するHDRレンダリングのことです。処理負荷が大きくなり、使用するメモリも多くなります。light11.hatenadiary.comそこで、浮動小数点バッファを使わずにHDRレンダリング的なことをやろうというのが疑似HDRの考え方です。今回紹介するのはスケーリングによる擬似HDRです。これは、オブジェクトを描画するときにシェーダで計算された値を2で割ったものをLDRテクスチャに格納します。これにより、本来0〜2の範囲にあった値が0〜1としてLDRのテクスチャに書き込まれます。ポストエフェクトなどでレンダリング結果を使う際には、LDRテクスチャに格納された値を2倍にします。これにより0〜2の範囲の値をポストエフェクトで扱えます。最後にポストエフェクトをかけた後の値をまた2で割ってLDRの値を最終結果とします。この手法は色の精度は落ちますが実装が簡単で使いやすいです。上記の考え方に基づいて疑似HDRを実装してみます。オブジェクトを描画するシェーダを書きます。"Diffuse"}diffuseでライティングしているだけの単純なシェーダです。最終的に計算された値を2分の1にスケールして出力しています。これにより、本来0~2の範囲の値がレンダーターゲットには0~1として書き込まれます。次にポストエフェクト用のシェーダを書きます。}}フラグメントシェーダで入力テクスチャの値を2倍しています。これにより、0~1で格納されていた値が本来の0~2の値に戻されます。今回は1以上の部分を出力しています。これが描画されれば、HDRの値をポストエフェクトに渡せたことになります。実装結果オブジェクト用のシェーダをCubeに適用し、ポストエフェクトを掛けてみます。LightのIntensityを1にしてみます。Gameビューに何も描画されないことが確認できます。これはLightのIntensityが1であるため、オブジェクトの色も0~1の範囲に収まってしまうためです。次にLightのIntensityを2にしてみます。物体色が1以上の値を示す部分だけ描画され、ポストエフェクトに1よりも大きい値を渡せていることが確認できました。ARGB2101010テクスチャを使う上述の方法では精度に問題があるため、精度の高いLDRテクスチャを使うように実装を変更してみます。RenderTextureFormat.ARGB2101010に対応している場合にはこちらを使うようにします。ES3.0では標準らしい(?)です。light11.hatenadiary.comソースコードは下記のようにします。}}これをカメラにアタッチして再生すると対応しているプラットフォームでARGB2101010が使われます。FrameDebuggerをみるとちゃんとフォーマットが変わっていることが確認できます。他の実装方法について上述の方法では色の精度が1/2に落ちてしまいますが、これを緩和するために、アルファチャンネルを使う方法があります。具体的には、RGBの値のうち最大の値の逆数をAチャンネルに保存し、RGBの値には元のRGBの値にAを掛けたものを格納します。この方法はGPUによるブレンディングや補間が効かず、あまり実用的とは言えません。そのため本記事では単純なスケーリングによる方法のみ紹介しています。デメリットについて疑似HDRにはメモリ使用量と処理負荷を抑えつつHDR値を扱えるというメリットがあります。一方で、今回紹介したように、疑似HDRを実装するにはSkyboxなども含めすべてのシェーダにスケール処理を加える必要があるというデメリットがあります。ポストエフェクトにも処理を加える必要がありますが、Bloomに限って言えば疑似HDRのスケール値に合わせてThresholdを下げることで対応できそうです。疑似HDRを扱う際はこれらのデメリットを考慮する必要がありそうです。»プロフィールUnityエンジニア。グラフィックスへの興味が強めです。Blur(渦巻ブラー)のポストエフェクトを実装する月別アーカイブはてなブログをはじめよう!halya_11さんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。