RenderingForwardRenderingで複数ライトを取り扱うときの挙動やシェーダの書き方をまとめました。Renderingでライトの影響を受けるシェーダを書くとき、パスに次のようなTagを書きます。}これを書くことにより、Unityがマテリアルにライトの情報を渡してくれてそれをシェーダで取り扱えるようになります。単純にディレクショナルライトの影響を受けるだけならLightModeがForwardBaseなパスのみを記述すれば十分ですが、シーンに二つ以上のライトがある場合は2パス目として下記のTagを記述したパスを追加する必要があります。}Unityで使われるライトの情報はこの二つのパスのいずれかに受け渡されます。前節のようにして受け渡されたライトの情報はシェーダ内で計算されますが、ライトの種類や重要度に応じて下記のいずれかの計算方法が選択されます。振り分けられ方としては、まずシーンにあるライトのうち一番重要度の大きいディレクショナルライトが1.で計算されます。それ以外のライトについては、重要度が高い順に前節に2、3、4に振り分けられていきます。この振り分けられ方は若干複雑ですが、マニュアルに詳しく書かれています。前節でライトの重要度という言葉を使っていますが、これは下記の要因によって決まります。Modeについては、Importantにすると2個目以降のライトは前節の2の計算方法で処理されます。ライトを増やせば増やすほどフラグメントシェーダが高価になっていきます。Importantにすると前節の3か4の計算方法で処理されます。そのうえで、明るさに応じて重要度が高いものを3で処理し、低いものは4で処理します。ModeがAutoの場合は明るさに応じて重要度を自動的に判断して計算方法を振り分けます。複数ライトを取り扱うシェーダを書くそれでは複数ライトを取り扱うシェーダを書いてみます。}}説明が必要そうな部分はコメントを書いていますが、下記でいくつか補足します。UNITY_SHOULD_SAMPLE_SH~#endifは頂点ライティング・球面調和ライティングをしている部分です。重要度の低いライトの情報がここに入ってきます。処理内容はUnityStandardCoreを参考にしつつ、ShadeSHPerVertexだけUnityStandardUtilsに依存してしまうのでShadeSH9に置き換えました。ForwardAddパスでライトの情報をとってきていますが、ディレクショナルライトとその他のライトでライトベクトルのとり方を変える必要があります。ディレクショナルライトであるかどうかは_WorldSpaceLightPos0.wに0が入っているかどうかで判定できる決まりがあるので、これを使って判定しています。一部をcgincludeファイルに書き出すことで2パスの処理を共通化できます。cgincludeファイルは次のように書きます。col;}次にシェーダを次のように変更します。}}これで共通化されました。結果レンダリング結果は次のようになります。複数のライトが無事反映されました。»プロフィールUnityエンジニア。グラフィックスへの興味が強めです。インストールから基本的な使い方・注意点まとめ【Unity】【エディタ拡張】テクスチャを指定したUV座標で切り取って保存する【Unity】指定したアセットのAssetBundle名を取得する【Unity】【シェーダ】スクリプトからVP行列を渡してシェーダで座標変換に使う【Unity】【シェーダ】FloatやVectorをリニアライズ対象にするGammaアトリビュート月別アーカイブはてなブログをはじめよう!halya_11さんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。