Unityシェーダーチュートリアル  ポストプロセスを使わずにトーンマッピングをする

シェーダー

建物のライティングをしているとだいたいこのような事になります。

Unity シェーダー トーンマッピング

 

特に壁が白とかベージュとか明るい系の色だと

照明付近がものすごく白飛びするのでとても下品です。

 

PC用コンテンツであればポストプロセスでトーンマッピングすれば良いのですが、

モバイル用コンテンツの場合、パフォーマンスの関係で使いたくなかったり、

うまく使えなかったりします。

 

かといってこのまま画として仕上げるわけにもいかないので、

AOを強めにかけてみたり、ライトの直接強度・間接強度をごにょごにょしてみたり。。。

などとやっていると、どんどん画が破綻していくわけです。。。

 

何か楽にいい感じになる方法はないものかとあれこれ考えていたら、

先日がっつり作業していたHDRPの事を思い出しました。

 

HDRPのシェーダーグラフでは、Override Baked GI という項目があり、

ベイク済みのライトマップをシェーダー内で直接編集することができます。

Unity シェーダー トーンマッピング

 

Standardシェーダーにはそのような項目はありませんが、

ビルトインシェーダーのファイルにちょっと追記すればできそうなのでやってみます。

 

 

 Standard ライティングモデルのコードを改造する

 デフォルトのシェーダーファイルを持ってくる

ビルトインのシェーダーコードは,Unity のインストールフォルダの中に入っています。

[インストールフォルダ → Editor → Data → CGIncludes] を開いてください。

 

数十個のシェーダーファイルの中に、UnityPBSLighting.cginc というファイルがあります。

このファイルをプロジェクトにインポートします。

同フォルダにシェーダーを新規作成すれば自動的に

インストールフォルダではなくこちらの UnitiyPBSLighting.cginc を読みにいきます。

 

 

 UnityPBSLighting.cginc を探る

UnityPBSLighting.cginc の中に以下のようなコードが含まれています。


※ 記述を省略しています

inline half4 LightingStandard (・・・) {・・・}

inline half4 LightingStandard_Deferred (・・・) {・・・}

 

これが、Standard シェーダーのライティングコードです。

上が Forward レンダリング用、

下が Deferred レンダリング用 です。

 

この2つのコードの中に、下記のような記述があります。


UNITY_BRDF_PBS (s.Albedo, specColor, oneMinusReflectivity, s.Smoothness, s.Normal, viewDir, gi.light, gi.indirect);

 

最後の引数の、 gi.indirect にライトマップの情報が入っており、

gi.indirect.diffuse で取得することができます。

これを UNITY_BRDF_PSB に渡す前に編集してしまおうというわけです。

 

 

 ライトマップにトーンマップをかける

以下の記事を参考に、ACES Filmic Tonemapping をやってみます。

今回はトーンマップをいろいろ作って遊んでみます。

 


gi.indirect.diffuse = saturate(

(gi.indirect.diffuse * (gi.indirect.diffuse * 2.51 + 0.03)) /

(gi.indirect.diffuse * (gi.indirect.diffuse * 2.43 + 0.59) + 0.14)

);

UNITY_BRDF_PBS (s.Albedo, specColor, oneMinusReflectivity, s.Smoothness, s.Normal, viewDir, gi.light, gi.indirect);

 

結果こうなりました。美しい。

Unity シェーダー トーンマッピング

 

トーンマップの式を変えてみたり、かける前と後でブレンドしてみたり、いろいろできそうですね。

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)