# 照明分布の形不一致の原因切り分け (Shape Mismatch Root-Cause Investigation)

本ドキュメントは，[TEST_08 面光源スケール軸バグ](TEST_08_面光源スケール軸バグの発見と修正.md) の修正後もなお残る**「照明分布の“形”が実機と一致しない」問題**について，原因を実験で切り分けていく継続記録である．

> **最優先の判定基準**: 本調査は CoV／勾配などの**数値の絶対量ではなく，実機マップとの「形の一致」**を唯一の判定基準とする．形が一致しない限り「筐体を仮想的に変えて結果を予測する」というツール本来の目的（筐体改善の事前検討）が成立しないため．判定には実機マップを参照とした **NCC／SSIM ＋ 視覚比較 ＋ 放射プロファイル**を用い，peak/mean（中心の尖り具合）を補助指標とする．

> **【重要・ROI 揃え更新】** 本ドキュメントの数値・図は **シミュを公式 ROI（`evaluation.roi_presets.SIM_ROI` = image_pixel(24,37,464,450)）で切り出し，実機 ROI（`REAL_ROI`，実機 npy は適用済み）と物理領域を揃えて**算出した版に更新済み．初期検証はシミュをフル 512² フレームのまま測っており（板の縁・周辺暗部を含む），peak/mean を ~0.07 過大・NCC を ~0.05 過小に見せていた．**ROI 揃えで NCC は +0.05 程度改善するが，結論（混ぜ具合・配光は本筋でない／形は実機に届かない／B1 幾何が最有力）は不変**．ROI 版の図は `output/_slide_panels/*_roi.png`．

## 出発点 — バグ修正後も「形」は不一致

TEST_08 の面光源バグ修正で**灯間バランス（下灯 2.1×）は解消**したが，各単灯・合成の**分布の形**は実機と一致しないまま：

- **実機 単灯**: ほぼ一様（peak/mean ≈ 1.2，放射プロファイルは中心 1.05 → 周辺 0.9 でほぼ平坦）
- **シミュ 単灯**: 中心が尖り（peak/mean ≈ 1.7）＋上暗下明の縦勾配，周辺の落ち込みが急

比較図: `output/_slide_panels/sim_vs_real_shape_roi.png` / `sim_vs_real_colormap_roi.png`（ROI 揃え）

## 重要な前提確認 — ディフューザーは存在しない

実機ハードの確認結果（ユーザー回答）：

- **LED カバー（`LED基板カバー*.stl`）は筐体と同じ不透明白材**（3D プリンタ白フィラメント，printer_white）．光は透過しない．
- **LED とは別のディフューザー（すりガラス・乳白アクリル・拡散シート等）は一切挟んでいない**．
- → 実機は **むき出し LED ＋ 白い筐体のみ**．

含意：**実機単灯のあの「平らさ」を作っているのは光学部品ではなく，白い筐体内の多重反射（積分球的な拡散）**でしかありえない．逆に言えば，形を再現する鍵は新部品ではなく**筐体（反射＋幾何）の正しいモデル化**にある．

## 重要な注意 — 過去の「形は変わらない」結論はバグ込み

[PROGRESS](../PROGRESS.md) に記録された「**A8 反射率・A9 max_depth・A1 BSDF を振っても形は変わらない**」という Step 8-14 の結論は，**すべて面光源バグ（2m 縦長ストリップ）が入った状態で得たもの**であり，TEST_07 と同様に**再検証が必要**．特に「筐体が光をかき混ぜて平らにする」効果は反射回数・反射率に依存するはずで，バグで巨大ストリップが支配していたため形が動かなかった可能性がある．本調査は**修正後の正しい LED で**やり直す．

## 実験1 — bottom 単灯 max_depth バウンス分解（spp=1024）

### 目的・条件

「形を平らにするレバーが現エミッタで存在するか」を確かめる第一歩．**bottom 単灯のみ・spp=1024 固定**で，**max_depth 以外をすべて一定**にし，反射回数を `{1, 2, 4, 8, 16, 32}` で振る．「バウンスを増やすほど実機の平らな形に近づくか／頭打ちか」を見る．

- config: `configs/_tmp_depth_bottom/d{1,2,4,8,16,32}.yaml`（`_tmp_sanity_1024/scene_bottom.yaml` ベース，max_depth のみ変更）
- 出力: `output/depth_bottom/d{N}/luminance.npy`
- 比較図: `output/_slide_panels/depth_bottom_shape_roi.png`（ROI 揃え）

### 結果

（数値は **ROI 揃え**版．図 `output/_slide_panels/depth_bottom_shape_roi.png`）

| max_depth | mean(参考,フル) | peak/mean(ROI) | NCC(ROI,対実機) |
| --- | --- | --- | --- |
| 1 | **0.000（真っ暗）** | – | – |
| 2 | **0.000（真っ暗）** | – | – |
| 4 | 1.474 | 2.073 | 0.731 |
| 8 | 3.484 | 1.730 | 0.735 |
| 16 | 4.678 | **1.585** | 0.720 |
| 32 | 4.904 | **1.591** | 0.717 |
| **実機 bottom** | – | **1.218** | – |

### 読み取れること

1. **depth=1, 2 が完全に真っ暗（mean=0）** → LED は板に背を向けており（emitter 法線 -Z，板は +Z 側），**板は完全に間接光のみ**で照らされる（3〜4 回反射してようやく到達）．TEST_08 で示した「LED は板と反対を向き間接光で照らす」を実証．
2. **バウンスを増やすと多少は平らになる**（peak/mean 2.07 → 1.59）が，**depth=16 で完全に頭打ち**（d16 と d32 がほぼ同一：1.585 vs 1.591，NCC 0.720 vs 0.717）．
3. しかし**頭打ちの到達点（peak/mean 1.59）が実機（1.22）に全く届かない**．NCC も 0.72 で頭打ち（むしろ深さとともに微減）．上暗下明の縦勾配も最後まで消えない．

### 解釈

- **「混ざり不足（バウンス不足）」は原因ではない**．反射を理論上限（d32）まで積んでもシミュは尖ったまま．
- **完全に閉じた白い箱なら，無限反射で必ず均一（積分球）になる**はず．シミュが d32 でも尖り＋縦勾配を残す＝**光が箱内で混ざりきる前にどこかへ逃げている**＝**シミュ筐体が実機ほど閉じていない（壁の欠け・隙間・開口）**疑いが濃厚．
- → 形の残差の本筋は **B1 筐体幾何**側にある可能性が高い，と実験で絞り込めた（反射回数では詰められない）．

## 実験2 — bottom 単灯 反射率スイープ（spp=1024, d=16）

### 目的・条件

実験1で「混ぜ不足ではない」と分かったため，**「反射率が足りないだけ」なのか「幾何が漏れている」のか**を切り分ける．**bottom 単灯・spp=1024・max_depth=16 固定**（実験1で d16≈d32 と反射飽和を確認済み）で，筐体材 `printer_white` の反射率を `{0.85, 0.90, 0.95, 0.98}` に上げる．holder_dark(0.5)・phone_body_dark(0.05) は据え置き．

- config: `configs/_tmp_refl_bottom/r{90,95,98}.yaml`（R=0.85 は実験1の `output/depth_bottom/d16` を再利用）
- 出力: `output/refl_bottom/run_r{90,95,98}/luminance.npy`
- 比較図: `output/_slide_panels/refl_bottom_shape_roi.png`（ROI 版）
- 判定: 閉じた箱なら R↑で一気に平ら（実機方向）→ 反射率の問題／漏れた箱なら R↑でも尖ったまま → 幾何（閉じ漏れ）が確定

### 結果（ROI 揃え）

| R (printer_white) | peak/mean(ROI) | top/bot(ROI) | NCC(ROI,対実機) |
| --- | --- | --- | --- |
| 0.85 | 1.585 | 0.879 | 0.720 |
| 0.90 | 1.541 | 0.890 | 0.714 |
| 0.95 | 1.408 | 0.901 | 0.708 |
| 0.98 | 1.392 | 0.908 | 0.701 |
| **実機 bottom** | **1.218** | **0.931** | – |

### 読み取れること

1. **R を上げると確かに少し平らになる**（peak/mean 1.59→1.39，縦勾配 top/bot 0.879→0.908 で実機方向）．
2. **しかし R=0.98（3D プリンタ白では非現実的に高い値）でも peak/mean 1.39 止まりで，実機 1.22 に届かない**．
3. **肝心の形の一致度（NCC）は改善しない**（0.720→0.701 でむしろ微減）．

### 解釈

- **反射率も「形の本筋」ではない**．実験1（バウンス回数）と実験2（反射率）で，**「筐体が光をかき混ぜる強さ」を司る 2 つのレバーを両方とも上限まで振っても，シミュは実機の平らさに構造的に届かない**ことが確定．NCC が頭打ち＝形の不一致は混ぜ具合では埋まらない．
- 反射率を上げても recirculation が効ききらない＝**箱が閉じておらず光が逃げている**疑いが，実験1（無限バウンスでも尖り＋縦勾配が残る）と整合して裏付けられた．
- → **形の残差の本筋は B1 筐体幾何（光の入り方・箱の閉じ方）に絞り込まれた**．

## 実験3 — bottom 単灯 配光（spot cutoff）スイープ（spp=1024, d=16）

### 目的・条件

LED の面積がバグ修正で正しくなったため，光源側の最後のレバー＝**配光（指向性）**を再検証する（過去 Step 8-14 の ξ 実験はバグ込みのため無効）．**bottom 単灯・spp=1024・max_depth=16 固定**で，Lambertian 面光源（現状）に対し spot emitter の cutoff_angle を `{15,30,60,90,120,150}°`（beam_width = cutoff/3）でスイープ．

- config: `configs/_tmp_distrib_bottom/c{015..150}.yaml`（bottom 6 灯のみ，`scene_baseline_spot.yaml` ベース）
- 出力: `output/distrib_bottom/c{NNN}/luminance.npy`，基準 area は `output/depth_bottom/d16`
- 比較図: `output/_slide_panels/distrib_bottom_shape_roi.png`（ROI 版）

### 結果（ROI 揃え）

| 光源 | peak/mean(ROI) | top/bot(ROI) | NCC(ROI,対実機) |
| --- | --- | --- | --- |
| area（Lambertian, 現状） | 1.585 | 0.879 | 0.720 |
| spot 15° | 1.950 | 0.761 | 0.652 |
| spot 30° | 1.657 | 0.800 | **0.737** |
| spot 60° | 1.443 | 0.861 | 0.730 |
| spot 90° | **1.436** | 0.879 | 0.722 |
| spot 120° | 1.704 | 0.883 | 0.705 |
| spot 150° | 1.828 | 0.883 | 0.681 |
| **実機 bottom** | **1.218** | **0.931** | – |

### 読み取れること

1. **中程度の spot（60〜90°）が最も平ら**（peak/mean 1.44）で Lambertian（1.59）よりわずかに改善．狭すぎ（15°→1.95）・広すぎ（150°→1.83）は悪化＝中庸が谷．
2. **最良でも peak/mean 1.44 で実機 1.22 に届かず，NCC は全域 0.65〜0.74 でほぼ横ばい**（最良 spot30 で 0.737，area 0.720 から誤差レベル）．
3. → **配光も形の決定的レバーではない**（動くが届かない）．物理的には板が間接光のみ＋Lambertian 拡散壁なので，配光を変えても背面壁への初当たりが変わるだけで拡散反射が大半を均す．

> **過去結論の訂正**: PROGRESS の Step 8-14「area→spot は形改善の本物候補（angular_ratio −25%）」は**バグ込み（2m ストリップ）の結論**であり，正しい面積で再検証すると効果は誤差レベル（NCC 0.72→0.74）．TEST_07 と同じく ξ も過大評価だった．

## 3 実験の総括と次の予定

| レバー | 実験 | 形への効果（ROI） | 判定 |
| --- | --- | --- | --- |
| 反射回数 max_depth | 実験1 | d16 で頭打ち，peak/mean 1.59 止まり | 本筋でない |
| 反射率 R | 実験2 | R=0.98 でも 1.39 止まり，NCC 改善せず | 本筋でない |
| 配光 ξ（spot cutoff） | 実験3 | 中庸 spot で 1.44 止まり，NCC 横ばい | 本筋でない |
| **筐体幾何 B1** | 実験4（予定） | — | **最有力（光源側レバー出尽くし）** |

光源側のレバー（反射回数・反射率・配光）を出し尽くしても形は実機に届かない＝**残るは筐体幾何のみ**．

### 次（実験4）— 幾何の漏れ点検

「光がどこから逃げているか／箱が閉じているか」を直接調べる：

- **漏れの定量化**: bottom 単灯で，放出フラックスのうち何割が評価板に届き，何割が開口から外へ逃げているかを測る
- **閉じテスト**: シミュ筐体の開いている面（センサ側開口など）を仮の白壁で塞いで再レンダ → 平らになれば「閉じ漏れ」が原因と確定

### 補足 — 実機の平らさの素性確認（実験4 前に要検討）

実機マップは **LSC 補正済み**（`dng_luminance(apply_lsc=True)`）．LSC はレンズ周辺減光を割り戻す処理で**本来は照明分布を平らにしない**はずだが，「実機の平らさが本物の照明分布か，処理由来か」を実験4 前に一度確認しておくと安全（[TECH_07 LSC 取り扱い方針](../05_TECH/TECH_07_LSC取り扱い方針.md) 参照）．

## 追加観察 — 修正後の 3 単灯は「形」がほぼ同一（実機の相補性を再現できていない）

なぜ光源の形（点 vs 2m 帯）を変えても板の形がほとんど変わらないのか（[TEST_08 §修正前後のカラーマップ比較](TEST_08_面光源スケール軸バグの発見と修正.md)）の物理的根拠は，**板が「間接光のみ（LED は板に背を向け，depth=1,2 が真っ暗）＋ Lambertian 拡散壁」で照らされ，形が光源でなく筐体で決まる**ため．拡散壁での多重反射が光源の形状情報を洗い流す（積分球の原理；壁が鏡面なら光源形状が板に焼き付くが Lambertian なので消える）．

この帰結として，**修正後シミュでは下・左・右の 3 単灯の「形」が互いにほぼ同一**になる（同じ筐体に光を注ぐため）．3 単灯どうしの形の一致度（mean 正規化，フル frame 計測）：

| ペア | NCC | SSIM |
| --- | --- | --- |
| bottom vs left | 0.924 | 0.401 |
| bottom vs right | 0.927 | 0.406 |
| left vs right | 0.913 | 0.360 |

→ **NCC ≈ 0.92 で 3 灯は互いにかなり似た形**．違いは「自分の側がほんの少し明るい」弱い横バイアスのみ（縦勾配 top/bot ≈ 0.85/1.06 が 3 灯ほぼ同一）．

**重要な含意**: [TEST_04（実機単灯比較）](TEST_07_LEDグループ別動作確認.md) では実機の 3 灯は**相補的に異なる方向を照らす**（下＝上側／左＝右寄り…）とされていた．しかし**修正後シミュは 3 灯ほぼ同じ形＝実機の「相補性」を再現できていない**．これは「シミュでは形が筐体で決まり LED 位置の効きが弱すぎる」ことを意味し，(a) 筐体幾何 B1 の不正確さ，または (b) シミュが間接化しすぎ（実機は各灯の直接性／指向性がもっと残る）を示唆する．実験4（幾何）の追加手がかり．

## 関連ドキュメント

- [TEST_08 面光源スケール軸バグの発見と修正](TEST_08_面光源スケール軸バグの発見と修正.md) — 本調査の前提（バグ修正で灯間バランスは解決済み）
- [TEST_07 LED グループ別動作確認](TEST_07_LEDグループ別動作確認.md) — バグ込みの旧結論（訂正済み）
- 実機入力: `lightsim/luminance_maps/bottom_*.npy`（単灯実測，`.gitignore` 対象）
