[Unity5]破綻しない半透明描画を行う

無題
Pocket

半透明の描画は非常に厄介です。

Unity5においてもそれは同じで、オブジェクト単位でソートされているため微妙なカメラ位置によって「パキッ」と手前/奥が切り替わってしまうような現象が見られます。

また、シェーダによって影の透明度を制御したい時に参考になる資料がなかったため、それについても少し調べてみました。

 

Alpha1

 

アルゴリズム

「ディザリング」を用いた手法を採用してみます。

これは所謂「トーン」を用いて擬似的に半透明を表現する手法で、見た目は少しザラつきすが、上記のソート順の問題などを解決できます。

また、特定のアルゴリズムのアンチエイリアスと組み合わせることでザラつきを軽減することができます(今回はやっていません)

Alpha2

 

事前にテクスチャに情報を書き出し、そのテクスチャを用いてライティングする「Diferred Shading」と相性がよく、それを採用している「MGSV: TPP」「LIGHTNING RETURNS : FINAL FANTASY XIII」「MOBIUS FINAL FANTASY」「LEGO®ムービー ザ・ゲーム」などの商用のゲームでも見かけることができます。

 

実装

思いの外情報が少なかったため、基本的にBuiltin ShaderのDefaultResourcesExtra/Standard.shaderを参考にしています。

Unity ダウンロード アーカイブ

 

ディザリングはUnity5標準の影の描画でも使われているため、デフォルトで「_DitherMaskLOD」という名前の3Dテクスチャが定義されています。

x/yにスクリーン座標、zにアルファ値を指定することで、そのピクセルが透明かどうか(透明なら0、違えば1)を取得できます。

これをそのままclip関数へ渡してやれば、ディザリングを用いた描画の実装は完了です。

 

シェーダで面を円形に切り抜きたかったため、ShadowCasterパスを定義し直しています。

UnityStandardShadow.cgincをinclude、標準のvertShadowCaster/fragShadowCasterの代わりに自前で定義したfrag/vert関数を使い、その中で切り抜きを行っています。

 

ソースコード

 

動作

標準の透明マテリアルと違い、カメラを動かしても破綻しません。

Alpha3

Pocket

コメントを残す

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

(Required)

Proudly powered by WordPress   Premium Style Theme by www.gopiplus.com