UnityでUV-C光を可視化する|ハコブくん病院フロアのマテリアル管理とシェーダー設計
病院のフロアをプログラムで生成した瞬間、画面が漆黒に包まれる。何度パラメータを調整しても、壁やベッドは不気味な黒や異常な青白さを放つばかり。この「操作のノイズ」は、単なる数値のミスではなく、Unityのライティングシステムとスクリプトによる動的なオブジェクト生成が衝突した結果でした。
※薬剤搬送ロボットハコブくんは技術検証用の仮想設定です。 実用化目的ではなく、制御・UIデザイン・HRI(人間とロボットの相互作用)の本質を探求するコンセプトとして定義しています。
マテリアル生成の改修
実行時のマテリアル乱用を抑制する
病院の構造物を生成する際、一つひとつのオブジェクトに対して個別にマテリアルを生成していたことが、描画の破綻を招いていました。Unityにとって、実行時に生成された未知のマテリアルは「ライティングの計算結果が存在しない物体」であり、結果として影の計算が正しく行われず、真っ黒な出力を招いていました。
実装のステップ: MeshRenderer の material プロパティに対して実行中に new Material を割り当てる処理を廃止し、Unityが標準で提供している Default-Material をそのまま参照するようにコードを書き換えます。具体的には Shader.Find を使用した動的なシェーダー検索とインスタンス化を停止し、既存のアセット設定を維持したまま壁やベッドのメッシュを生成するフローへと変更しました。
設計の意図: Unityのライティングエンジンに対して「未知の物質」を突きつけるのではなく、あらかじめ計算可能な標準マテリアルを使用することで、ライトマップとの整合性を保つのが狙いです。これにより、計算リソースの浪費を防ぎ、全ての壁面に一貫した光の反射を保証しました。
環境光設定の復元
室内空間の「光の底上げ」を再定義する
病院のように屋根や厚い壁に囲まれた構造では、外部からの光が遮断されます。シンプルさを求めて削ぎ落とした一行のコードが、室内から物理的な光を奪い去っていました。
実装のステップ: スクリプト内の初期化プロセスにおいて RenderSettings.ambientLight に対して Color の値を 0.7f 、 0.7f 、 0.7f で再設定する記述を復旧させました。これにより、シーン全体に均一な環境光を供給し、直接光が届かない場所でも形状が視認できる明るさを確保しました。
設計の意図: 物理ベースのレンダリングにおいて、完全な暗闇を回避するための「視覚的なセーフティネット」を張ることが目的です。環境光を適切なグレー( 0.7f )に固定することで、ユーザーがどの角度からフロアを見渡しても、壁やオブジェクトの立体感を直感的に把握できる安心感を提供します。
マテリアル・インスタンシングの最適化
メモリと描画バッファの調和
色を変更しようとして material.color を書き換えるたびに、Unity内部ではそのオブジェクト専用のコピーが作られます。数百枚の壁が存在する病院フロアでは、この挙動がライティングバッファを破壊する原因となっていました。
実装のステップ: 個別のオブジェクトごとに色を書き換えるのではなく、共有されたマテリアルのプロパティを維持したまま描画する設計に移行しました。個別のマテリアルインスタンスを発生させないよう、スクリプトによる Color 指定の乱用を控え、ベースとなる設定を死守した状態でフロア全体を構築しました。
設計の意図: 「シマシマ」や「ムラ」といった描画のバグを排除し、フロア全体の視覚的な統一感を出すための決断です。個別の色操作をあえて制限することで、Unityのライティングエンジンが最も得意とする「静的なライトマップの美しさ」を最大限に引き出す設計としました。
原因分析のまとめ
new Material()によるライティング破綻: 実行時のマテリアル生成がUnity 6のライトマップ計算と衝突し、影を真っ黒に処理させていた。環境光(Ambient Light)設定の消失: 室内という閉鎖空間において、全体の明るさを底上げする設定が消えたため、物理的に光が届かなくなった。
マテリアル乱立によるバグ: 大量の壁に個別のマテリアルを割り当てたことで、描画エンジンが正常な色を返せなくなった。
生成AIに全てを行わせて原因追求しないと、プロセスがブラックボックス化してしまいます。そのため、今後も問題が発生した際は必ず検証と分析を行い、何が根本的な原因だったのかを徹底的に追求し、理解した上で次へ進むようにしてください。
