diff --git a/CLAUDE.md b/CLAUDE.md index ef5f3b8..47f6d2b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,7 +23,7 @@ ## 開発進捗 -最新: フェーズ 7(実装)— **TEST_18 照明配置依存性の球と立方体の比較**(LED の位置 θ・向き・個数を同内面積ペアで振った 255 条件.配置依存は球が立方体の 1/2〜1/3,対向 2 灯以上で形状差が消える.校正材質 ρ=0.81 でも結論不変(軸上は両形状とも最良になる).真下向き多灯はバッフル無しで成立するが板向き多灯に劣る)と,**スイープの高速化**(`sm-render`/`sm-evaluate` の本体を `render/pipeline`・`evaluation/pipeline` に関数化してプロセス内実行,`--no-figures`,遮蔽検証を cuda で,`--workers 2`.1 条件 球 40 秒 → 6 秒).サーバは `sm-remote`(学外からは `SM_REMOTE_HOST=Newton-via-lab`).**環境**: mitsuba は **3.7.1 に固定**(テストは `uv run python -m pytest`),開発機の **SAC はオフ**(ENV_04 参照).同一 seed の再レンダは集計指標が一致するので,ノイズフロアは `render.seed` を変えて測る.詳細は [docs/PROGRESS.md](docs/PROGRESS.md). +最新: フェーズ 7(実装)— **TEST_18 照明配置依存性の球と立方体の比較**(LED の位置 θ・向き・個数を同内面積ペアで振った 255 条件.配置依存は球が立方体の 1/2〜1/3,対向 2 灯以上で形状差が消える.校正材質 ρ=0.81 でも結論不変(軸上は両形状とも最良になる).真下向き多灯はバッフル無しで成立するが板向き多灯に劣る)と,**スイープの高速化**(`sm-render`/`sm-evaluate` の本体を `render/pipeline`・`evaluation/pipeline` に関数化してプロセス内実行,`--no-figures`,遮蔽検証を cuda で,`--workers 2`.1 条件 球 40 秒 → 6 秒).サーバは `sm-remote`(学外からは `SM_REMOTE_HOST=Newton-via-lab`).**環境**: mitsuba は **3.7.1 に固定**(テストは `uv run python -m pytest`),開発機の **SAC はオフ**(ENV_04 参照).同一 seed の再レンダは集計指標が一致するので,ノイズフロアは `render.seed` を変えて測る.**spp の指針**([TEST_19](docs/06_TEST/TEST_19_sppと計算時間ノイズ指標安定性.md)): GPU 時間は spp に比例(1024 で 5 秒)・固定費 0.8 秒・ノイズは 1/√spp 則.構造 CoV なら 1024,画像全体 min/max 比を暗い条件で比べるなら 2048〜4096.詳細は [docs/PROGRESS.md](docs/PROGRESS.md). 実装済みモジュール: - `src/sm_tias_lightsim/uniformity.py` — Rec.709 輝度変換 + CoV/std/max-min(SmTIAS-Evaluation コピー) @@ -156,4 +156,5 @@ - バッフル導入と球半径スイープ: docs/06_TEST/TEST_15_バッフル導入と球半径スイープ.md(LED 壁面密着+バッフルで直接光を遮る新構成と,球内半径 88〜250mm のスイープ.ロフト接合の 2 段階の作り直しで「大きいほど悪化」が逆転し,板直下の喉が最大のレバーと判明した経緯) - 立方体キャビティ導入と球との比較: docs/06_TEST/TEST_16_立方体キャビティ導入と球との比較.md(ロフト・接合・喉の無い立方体を L=120〜360mm でスイープし内面積で球と対応づけ.同面積なら立方体が一貫して均一で,四隅の写り込みは m=4 方位フーリエで検出限界以下と確認) - オフ軸 LED 配置の影響とサイズ依存: docs/06_TEST/TEST_17_オフ軸LED配置の影響とサイズ依存.md(LED を側壁に置いた非対称の定量.サイズとともに減衰するが,頑健性は球 > 立方体で軸上の優劣と逆転.明るくなるのは LED の反対側) +- spp と計算時間・ノイズ・指標の安定性: docs/06_TEST/TEST_19_sppと計算時間ノイズ指標安定性.md(spp 256〜8192 × 6 条件.GPU 時間は spp に比例・固定費 0.8 秒,ノイズは 1/√spp 則に一致.構造 CoV は 1024 で十分,画像全体 min/max 比を暗い条件で比べるなら 2048〜4096) - 照明配置依存性の球と立方体の比較: docs/06_TEST/TEST_18_照明配置依存性の球と立方体の比較.md(LED の位置 θ・向き・個数を同内面積ペアで振った 198 条件.配置依存は球が立方体の 1/2〜1/3,対向 2 灯以上で形状差が消える.追加実験: 立方体は面の稜へ寄せると悪化,真下向き多灯はバッフル無しで成立するが板向き多灯には劣る,校正材質 ρ=0.81 でも結論不変だが軸上は両形状とも最良になる) diff --git "a/docs/02_ENV/ENV_04_\351\226\213\347\231\272\343\202\263\343\203\236\343\203\263\343\203\211.md" "b/docs/02_ENV/ENV_04_\351\226\213\347\231\272\343\202\263\343\203\236\343\203\263\343\203\211.md" index 3237bfa..fad4f0d 100644 --- "a/docs/02_ENV/ENV_04_\351\226\213\347\231\272\343\202\263\343\203\236\343\203\263\343\203\211.md" +++ "b/docs/02_ENV/ENV_04_\351\226\213\347\231\272\343\202\263\343\203\236\343\203\263\343\203\211.md" @@ -108,6 +108,7 @@ - CPU(`llvm_*` / `scalar_*`)で回すときは `--threads N` で Dr.Jit のスレッド数に上限を付ける(共用サーバの 64 スレッドを占有しないため) - GPU で回すときの CPU 負荷は小さい(球 10 条件のスイープで CPU は平均 156%・最大 342%=64 スレッド中 1.5〜3.4 スレッド分.2026-09-13 実測).1 本のスイープに GPU は 1 枚(`--gpu`)で足りる - **スイープの 1 条件あたりの内訳**(`scripts/profile_sweep_step.py` で計測.2026-09-14 Newton GPU 0・spp=1024・512²): GPU のレンダ本体 4.4〜5.2 秒が床.旧方式(`uv run sm-render` / `sm-evaluate` をサブプロセスで呼ぶ)はそれに起動・import・YAML・PLY 書き出しで約 2.5 秒,図の描画で約 2 秒が乗り,さらに遮蔽検証(`verify_baffle_occlusion`)を YAML の llvm で回すと球で約 25 秒かかっていた.`scripts/sweep_led_placement.py` 以降のスイープは `render/pipeline.py:render_yaml` と `evaluation/pipeline.py:evaluate_image(save_figures=False)` をプロセス内で呼び,`runner.ensure_variant` で先に cuda を確定してから遮蔽検証する(球 40 秒 → 約 6 秒,立方体 13 秒 → 5.5 秒).`--workers N` で同じ GPU に複数プロセスを載せられるが,GPU 律速なので実測は 1→5.5 秒・2→5.0 秒・3→4.5〜5.8 秒(1 条件あたり).**`--workers 2` を既定の推奨**とする(CPU 側の処理を隠す分だけ得.3 以上は効果なし) +- **spp の指針**([TEST_19](../06_TEST/TEST_19_sppと計算時間ノイズ指標安定性.md)): GPU のレンダ時間は spp に厳密に比例(1024 で 5.1 秒・2048 で 10.3 秒・4096 で 20.1 秒)で,CPU 側の固定費は 0.8 秒(PLY 書き出し 0.34・評価 0.29・保存 0.12).ノイズは 1/√spp 則に乗る.構造 CoV は 1024 で安定,画像全体 min/max 比を生 mean < 0.2 の暗い条件まで比べるなら 2048〜4096 - 同一シーンを seed を変えずに再レンダしても集計指標は 4 桁まで一致する(画素はノイズ程度に変わるが集計では消える).**ノイズフロアを測るときは `render.seed` を変える**(`RenderConfig.seed`.`sweep_led_placement.py` の再現性条件は rep ごとに seed を変えた YAML を書く) - GPU は `status` で空きを見てから `--gpu` で指定する(未指定だと CUDA は 0 番を使う).その他の環境変数は `--env KEY=VALUE` で渡せる - サーバで pytest を回すときは `--yaml-variant` を付ける(variant の上書きをテストに持ち込まないため): `uv run sm-remote run --name pytest-all --yaml-variant -- python -m pytest -m ""` diff --git "a/docs/06_TEST/TEST_02_\343\202\267\343\203\237\343\203\245\343\203\254\343\203\274\343\202\267\343\203\247\343\203\263\345\256\237\350\241\214\350\250\230\351\214\262.md" "b/docs/06_TEST/TEST_02_\343\202\267\343\203\237\343\203\245\343\203\254\343\203\274\343\202\267\343\203\247\343\203\263\345\256\237\350\241\214\350\250\230\351\214\262.md" index 18a2a5d..65f1ec3 100644 --- "a/docs/06_TEST/TEST_02_\343\202\267\343\203\237\343\203\245\343\203\254\343\203\274\343\202\267\343\203\247\343\203\263\345\256\237\350\241\214\350\250\230\351\214\262.md" +++ "b/docs/06_TEST/TEST_02_\343\202\267\343\203\237\343\203\245\343\203\254\343\203\274\343\202\267\343\203\247\343\203\263\345\256\237\350\241\214\350\250\230\351\214\262.md" @@ -92,6 +92,7 @@ | `output/offaxis_led_sweep/` (10 ディレクトリ) | TEST_17 | `configs/_tmp_offaxis/scene_offaxis_*.yaml`(`scripts/sweep_offaxis_led.py` が生成.LED を**深さ方向軸の中点の高さ・+X 側の壁面**に置き板中心 (0,0,-4.5) へ向けた board_baffle 構成.球 similar_radial r ∈ {88, 100, 135, 170, 250} + 立方体 L ∈ {120, 160, 200, 280, 360}.バッフルは視線上 10mm・数値サイジング.材質・spp=1024・d=16 据え置き・mitsuba 3.7.1) | `configs/eval_baseline_dng_target_shape.yaml` | m=1 符号付き a1 が全条件で負(LED 側が暗い)= -1.6〜-7.2%.サイズとともに約 4 割まで減衰.位置ずれの Δ構造CoV は球 ±0.006 以内・立方体 +0.010〜+0.033 — [TEST_17](TEST_17_オフ軸LED配置の影響とサイズ依存.md) 参照 | **オフ軸頑健性は球 > 立方体(軸上と逆転)**を実証.遮蔽は全 10 条件 55,473 本 100%(傾き追従の LED サンプルに一般化済み) | | `output/offaxis_led_sweep/{summary.csv,offaxis_comparison.png}`・`_placement_check/cutaway_*.png` | TEST_17 | — | — | 条件別集約 CSV/解析図(輝度マップ 2 行 + a1・重心・構造 CoV の内面積依存を軸上と重ね描き)/レンダ前 3D 確認の半割り断面 10 枚 | `scripts/build_offaxis_comparison.py`・`show_scene_cutaway.py` の出力.レンダ前 3D 確認(CLAUDE.md 必須ルール)の記録を兼ねる | | `output/led_placement_sweep/` (255 ディレクトリ) | TEST_18 | `configs/_tmp_led_placement/scene_*.yaml`(`scripts/sweep_led_placement.py` が生成.同内面積ペア 球 φ ∈ {200,270,340,500}(r ∈ {100,135,170,250}) ↔ 立方体 L ∈ {141,187,234,340} で,LED をキャビティ中心から見た極角 θ=0〜120°(13 段階)に置く位置スイープ・θ=60/90/120° の向き 3 通り(板向き+バッフル/壁法線向き+バッフル/真下向き)・θ=90° の輪に N=1〜4 灯(総光束保存)・seed 違いの再レンダ,追加実験の方位角 φ=15〜40°(立方体)と真下向き N=2/4/8 灯.材質・spp=1024・d=16 据え置き.Newton cuda_ad_rgb・mitsuba 3.7.1・`--workers 2` で 1 条件 5〜6 秒) | `configs/eval_baseline_dng_target_shape.yaml` | 配置依存の幅(θ 全域の構造 CoV max−min)は球 0.015〜0.023・立方体 0.025〜0.071.球は θ≈30° が軸上より均一(φ340: 0.0193→0.0057).対向 2 灯で構造 CoV 0.005〜0.010 と形状差が消える.真下向きはバッフル無しで板向きと同等 — [TEST_18](TEST_18_照明配置依存性の球と立方体の比較.md) 参照 | **配置依存は球が立方体の 1/2〜1/3**(仮説成立).図なし評価(`--no-figures`)なので各条件に figures/ は無い.`row.json` が条件ごとの集約行(並列・再開用) | +| `output/spp_noise_sweep/` (72 ディレクトリ + `summary.csv` / `spp_summary_table.csv` / `spp_noise.png`) | TEST_19 | `configs/_tmp_spp_noise/scene_*.yaml`(`scripts/sweep_spp_noise.py` が TEST_18 の 6 条件の YAML を流用し spp と seed だけ書き換えて生成.球 φ340 軸上/θ=90°・立方体 L=234 軸上/θ=90°・球 φ500 θ=90°・立方体 L=340 θ=90° × spp 256〜8192 × seed 2.Newton GPU 0・cuda・逐次) | `configs/eval_baseline_dng_target_shape.yaml` | GPU 時間は spp に比例(1024 で 5.1 秒),固定費 0.8 秒.ノイズは 1/√spp 則に ±2% で一致.構造 CoV は 1024 で安定,画像全体 min/max は暗い条件で 2048〜4096 が必要 — [TEST_19](TEST_19_sppと計算時間ノイズ指標安定性.md) 参照 | 段階別の壁時計(`mi.render` は `dr.sync_thread` で同期)と seed 差を row.json に記録.`build_spp_noise_comparison.py` で図・表 | | `output/led_placement_sweep_rho081/` (60 ディレクトリ + 解析出力) | TEST_18 | `configs/_tmp_led_placement_rho081/scene_*.yaml`(`sweep_led_placement.py --material calibrated --key-subset` が生成.内壁を TEST_14 の校正材質 純 diffuse ρ=0.81 に置き換えた主要 60 条件=位置スイープ ペア 1・3,多灯 N=2/4・真下向き ペア 3) | 同上 | 配置依存の幅 球 0.030 vs 立方体 0.077〜0.098.軸上は両形状とも大きく改善(旧材質の光沢が作るリングが消える)— [TEST_18](TEST_18_照明配置依存性の球と立方体の比較.md) 結果 7 | 主結論が材質に依らないことの確認.解析は `build_led_placement_comparison.py --material calibrated` | | `output/led_placement_sweep/{summary.csv,analysis.csv,position_summary.csv,position_sensitivity.png,position_maps.png,direction_comparison.png,count_comparison.png,azimuth_comparison.png,ring_comparison.png,analysis_report.txt}`・`_placement_check/cutaway_*.png` | TEST_18 | — | — | 条件別集約 CSV/方位フーリエ m=1〜4・構造 CoV・重心の解析 CSV/位置・向き・灯数・方位角・真下向き多灯の解析図 6 枚/レンダ前 3D 確認の半割り断面 23 枚 | `scripts/build_led_placement_comparison.py`・`show_scene_cutaway.py` の出力.レンダ前 3D 確認(CLAUDE.md 必須ルール)の記録を兼ねる | | `output/cube_size_sweep/board_baffle/{summary.csv,cube_vs_sphere.png,fourfold_component.png}`・`output/cube_size_sweep/_placement_check/cutaway_L*.png` | TEST_16 | — | — | 条件別集約 CSV/球との比較図(輝度マップ 5 枚 + 輪帯プロファイル + 内面積軸の指標カーブ + 直接ペア 3 組)/m=4(cos 4φ)成分の定量図/レンダ前 3D 確認の半割り断面 5 枚 | `scripts/build_cube_sphere_comparison.py`・`analyze_fourfold_component.py`・`show_scene_cutaway.py` の出力.m=4 は全条件 \|a4\| ≤ 0.26%(系統誤差床 ~0.1%)=四隅の写り込みは実質ゼロ.レンダ前 3D 確認(CLAUDE.md 必須ルール)の記録を兼ねる | @@ -153,6 +154,7 @@ | レンダ前 3D 配置確認 (幾何変更時必須) | `uv run sm-visualize --scene --no-bake --screenshot ` + `uv run python scripts/show_led_geometry.py --scene --screenshot ` | | 球ロフト円形光源版レンダ・評価 (TEST_11 追補) | `$env:DRJIT_LIBLLVM_PATH = "C:\Program Files\LLVM\bin\LLVM-C.dll"; uv run sm-render --scene configs/scene_sphere_r100_loft_disk.yaml --output output/sphere_r100_loft_disk/` → `uv run sm-evaluate --image output/sphere_r100_loft_disk/luminance.npy --config configs/eval_baseline_dng_target_shape.yaml --output output/sphere_r100_loft_disk/` | | 単灯再検証レンダ・集計 (TEST_12 追補) | `$env:DRJIT_LIBLLVM_PATH = "C:\Program Files\LLVM\bin\LLVM-C.dll"; uv run sm-render --scene configs/_tmp_fix_{bottom,left,right}.yaml --output output/singles_fix/{bottom,left,right}/` → `uv run python scripts/build_singles_fix_summary.py` | +| spp スイープ (TEST_19) | `uv run python scripts/sweep_spp_noise.py --prepare-only` → `uv run sm-remote push` → `uv run sm-remote run --name spp --gpu 0 --threads 16 -- python scripts/sweep_spp_noise.py` → `uv run sm-remote pull spp_noise_sweep` → `uv run python scripts/build_spp_noise_comparison.py` | | 照明配置スイープ (TEST_18) | `uv run sm-remote push` → `uv run sm-remote run --name place --gpu 0 --threads 16 -- python scripts/sweep_led_placement.py --workers 2` → `uv run sm-remote pull led_placement_sweep` → `uv run python scripts/build_led_placement_comparison.py`(手元で幾何だけ確認するなら `--prepare-only`) | ## 過去の整理実績 (Cleanup History) diff --git "a/docs/06_TEST/TEST_19_spp\343\201\250\350\250\210\347\256\227\346\231\202\351\226\223\343\203\216\343\202\244\343\202\272\346\214\207\346\250\231\345\256\211\345\256\232\346\200\247.md" "b/docs/06_TEST/TEST_19_spp\343\201\250\350\250\210\347\256\227\346\231\202\351\226\223\343\203\216\343\202\244\343\202\272\346\214\207\346\250\231\345\256\211\345\256\232\346\200\247.md" new file mode 100644 index 0000000..3d5baa7 --- /dev/null +++ "b/docs/06_TEST/TEST_19_spp\343\201\250\350\250\210\347\256\227\346\231\202\351\226\223\343\203\216\343\202\244\343\202\272\346\214\207\346\250\231\345\256\211\345\256\232\346\200\247.md" @@ -0,0 +1,129 @@ +# spp と計算時間・ノイズ・指標の安定性 (Samples per Pixel vs Time, Noise, and Metric Stability) + +TEST_18 までのレンダは spp=1024 固定で,大きいキャビティほど生の輝度が低く相対ノイズが +7〜26% に達していた(指標はノイズ補正で救っている).研究室サーバの GPU で 1 条件 5 秒に +なったので,spp を 256〜8192 で振り,**(1) 計算時間のうち GPU が何秒か,(2) ノイズが +1/√spp で下がるか,(3) 各指標がどの spp で安定するか**を測って今後の標準 spp を決めた +(2026-09-14).結論: **GPU 時間は spp に厳密に比例し固定費は 0.8 秒.ノイズは 1/√spp 則に +正確に乗る.構造 CoV は 1024 で十分,画像全体 min/max 比を暗い条件で比べるなら 2048〜4096**. + +関連: + +- 高速化の内訳と `--workers`: [ENV_04 開発コマンド](../02_ENV/ENV_04_開発コマンド.md)「研究室サーバでの実行」 +- 指標の定義(構造 CoV・画像全体 min/max 比): [SPEC_04 評価仕様](../04_SPEC/SPEC_04_評価仕様.md),[TEST_18](TEST_18_照明配置依存性の球と立方体の比較.md)「均一性の指標」 +- 実行記録: [TEST_02_シミュレーション実行記録](TEST_02_シミュレーション実行記録.md) + +## 実験条件 (Setup) + +- 条件: TEST_18 の 6 条件の YAML を流用(spp と seed だけ書き換え).球 φ340 の軸上と θ=90°, + 立方体 L=234 の軸上と θ=90°,ノイズが最も大きい球 φ500 θ=90° と立方体 L=340 θ=90°. + 1 灯・板向き・バッフル付き,旧材質(ρ=0.85 blendbsdf),512²,max_depth=16 +- spp: 256 / 512 / 1024 / 2048 / 4096 / 8192(2 倍刻み)× seed 2 つ=72 レンダ.16384 は + ユーザー都合で未実施(12 レンダ・約 17 分) +- 計測: 段階別の壁時計(YAML 読込 / PLY 書き出し / シーン読込 / `mi.render` / 保存 / 評価). + `mi.render` は `dr.sync_thread()` で GPU の完了を待ってから測る(投げっぱなしで短く見える + ことを防ぐ).GPU 率 = `mi.render` ÷ 全体 +- 指標: 残差ノイズ CoV(生 − 平滑化)・構造 CoV・輪帯平均 min/max・画像全体 min/max + (ノイズ補正あり/なし)・ノイズ場の極値 +- 環境: Newton GPU 0(RTX A6000)・cuda_ad_rgb・mitsuba 3.7.1・`SM_DRJIT_THREADS=16`・逐次実行 + +## 結果 1 — 計算時間: GPU は spp に比例,固定費は 0.8 秒 (Time) + +6 条件 × 2 seed の平均. + +| spp | 全体 [s] | GPU(`mi.render`)[s] | CPU 固定費 [s] | GPU の割合 | +| --- | --- | --- | --- | --- | +| 256 | 2.0 | 1.2 | 0.8 | 60% | +| 512 | 3.2 | 2.5 | 0.8 | 76% | +| 1024 | 5.9 | 5.1 | 0.8 | 87% | +| 2048 | 11.1 | 10.3 | 0.8 | 93% | +| 4096 | 20.9 | 20.1 | 0.8 | 96% | +| 8192 | 40.6 | 39.8 | 0.7 | 98% | + +- **GPU 時間は spp に厳密に比例**(1024 spp あたり 5.0 秒.条件による差は ±10%.球がやや遅い) +- **固定費は 0.75〜0.8 秒で spp に依らず一定**.内訳は PLY 書き出し 0.34 秒・評価(図なし)0.29 秒・ + 保存 0.12 秒・YAML 読込とシーン読込(OptiX の BVH 構築を含む)は各 0.01 秒 +- spp ≥ 1024 で固定費は 1 割以下.CPU 側をこれ以上削る意味は薄い.256 では 4 割を占めるので, + 低 spp を多数回す用途なら筐体メッシュの PLY キャッシュが効く + +## 結果 2 — ノイズは 1/√spp 則に正確に乗る (Noise) + +| 条件 | 生 mean | ノイズ CoV(1024) | ノイズ × √spp(6 段階の範囲) | +| --- | --- | --- | --- | +| 球 φ340 軸上 | 0.355 | 0.092 | 2.93〜2.99 | +| 球 φ340 θ=90° | 0.323 | 0.145 | 4.63〜4.67 | +| 立方体 L=234 軸上 | 0.387 | 0.104 | 3.30〜3.32 | +| 立方体 L=234 θ=90° | 0.356 | 0.156 | 4.97〜5.08 | +| 球 φ500 θ=90° | 0.153 | 0.189 | 5.84〜6.05 | +| 立方体 L=340 θ=90° | 0.174 | 0.200 | 6.23〜6.38 | + +- ノイズ × √spp は全条件で ±1〜2% 以内で一定=**MC ノイズだけで,レンダ側に別のノイズ源は無い** +- ノイズ量は生の輝度で決まる(暗いほど大きい)が,同じ明るさでも軸上より θ=90° が 1.5 倍大きい + (オフ軸は一次照射キャップの経路分散が大きい).大キャビティを球 φ340 軸上と同じノイズにするには + spp を 4〜5 倍要る +- 画像全体 min/max のノイズ補正量(ノイズ場の max − min)も 1/√spp で減り,8192 で平均の 1% 以下 + +## 結果 3 — 指標の安定性 (Metric Stability) + +`spp_noise.png` 下段.誤差棒は seed 2 つの差の半分. + +| 指標 | 1024 での状態 | 安定する spp | +| --- | --- | --- | +| 構造 CoV | 256→1024 で 5〜15% 低下後ほぼ一定.seed 差 ≤0.0005 | **1024 で十分**(8192 との差 ≤0.002) | +| 画像全体 min/max(補正あり) | 明るい条件は安定(seed 差 0.003).暗い φ500・L=340 は 0.93〜0.94 で seed 差 0.01 | **2048〜4096**(暗い条件が 0.95〜0.96 に収束し seed 差 0.002) | +| 画像全体 min/max(補正なし) | どの条件も spp とともに上昇し続ける | 8192 でも収束しない(ノイズ補正は必須) | +| 輪帯平均 min/max | θ=90° で 0.97〜0.99 に張り付き,seed 差 0.003〜0.01 | spp では改善しない(方位平均の問題) | + +- **spp=1024 は構造 CoV には十分だが,画像全体 min/max 比は暗い条件で 0.01〜0.02 過小評価**していた + (TEST_18 の min の値のうち球 φ500・立方体 L=340 はその分だけ低めに出ている.順位は変わらない) +- 補正なしの平滑化 min/max は spp を 32 倍にしても収束せず,補正の必要性を裏付ける + +## 結論と推奨 (Conclusions) + +- **標準 spp**: 構造 CoV・方位フーリエ・重心で比べる実験は **1024** のまま(5.9 秒/条件).画像全体 + min/max 比を暗い条件(生 mean < 0.2)まで含めて比べる実験は **2048〜4096**(11〜21 秒/条件. + 255 条件で 50〜90 分) +- **CPU 側の最適化はここまで**.固定費 0.8 秒は spp ≥ 1024 で 1 割以下 +- ノイズは 1/√spp 則に乗るので,必要な spp は「目標ノイズ ÷ 1024 でのノイズ」の 2 乗で見積もれる + +## 限界・注意点 (Limitations) + +- 16384 は未実施.傾向は 8192 までで単調に収束しているため結論は変わらない見込み +- nvidia-smi のサンプリングは,ジョブ再起動時の `pkill` がサンプラー自身を止めたため記録が無い. + GPU 時間は `dr.sync_thread()` で同期した実測で取れているので結論には影響しない +- 条件は 6 つ(1 灯・板向き).多灯やバッフル無しは未測定だが,ノイズは生の輝度で決まるので + 同じ関係が成り立つはず +- 時間は逐次実行の値.`--workers 2` では 1 条件あたり 1 割ほど短くなる(ENV_04) + +## 失敗パターン・方法論の学び (Pitfalls and Methodology) + +- **`mi.render` の時間は同期してから測る**.cuda variant では非同期に GPU へ投げられるので, + `dr.eval` + `dr.sync_thread()` を挟まないと数十 ms に見える +- **サーバへの push は `--only scripts` だけだと足りないことがある**.新しい src モジュール + (`evaluation/fullimage.py`)を使うスクリプトは,全体を push してから回す +- **併走プロセスの `pkill -f` は再起動時に自分も殺す**.サンプラーを再起動するなら先に止めてから + 起動する順序を守るか,PID ファイルで管理する + +## 再現コマンド (Reproduction) + +```bash +# YAML 生成(TEST_18 の _tmp_led_placement を流用するので先に sweep_led_placement.py --prepare-only) +uv run python scripts/sweep_spp_noise.py --prepare-only + +# サーバで実行(GPU 0).spp を絞るなら --spps 256 512 1024 +uv run sm-remote push +uv run sm-remote run --name spp --gpu 0 --threads 16 -- python scripts/sweep_spp_noise.py +uv run sm-remote pull spp_noise_sweep + +# 解析(図と表) +uv run python scripts/build_spp_noise_comparison.py +``` + +出力: `output/spp_noise_sweep/`(レンダ別 72 ディレクトリ + `summary.csv` + `spp_summary_table.csv` + +`spp_noise.png`). + +## 参照 (References) + +- [TEST_18_照明配置依存性の球と立方体の比較](TEST_18_照明配置依存性の球と立方体の比較.md): 流用した条件と指標の定義 +- [SPEC_04_評価仕様](../04_SPEC/SPEC_04_評価仕様.md): 画像全体 min/max 比の定義と注意 +- [ENV_04_開発コマンド](../02_ENV/ENV_04_開発コマンド.md): 高速化の内訳と `--workers` diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index 39c2d5c..3acd6e7 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -104,3 +104,5 @@ - **TEST_18 照明配置依存性の球と立方体の比較 — 配置依存は球が立方体の 1/2〜1/3 (2026-09-14)**: ユーザーの仮説「積分球が使われる理由は照明配置への依存が小さいから」を,同内面積 4 ペア(球 φ200/270/340/500(r=100/135/170/250)↔ 立方体 L=141/187/234/340)で **LED の位置(キャビティ中心から見た極角 θ=0〜120° を 13 段階)・向き(板向き+バッフル/壁法線向き+バッフル/真下向き)・個数(θ=90° の輪に N=1〜4)・再現性(seed 違い)** の 198 条件で検証した(Newton cuda・1 条件 5〜6 秒).**結果 ①**: θ 全域での構造 CoV の幅は球 0.015〜0.023・立方体 0.025〜0.071(1.2〜3.1 倍),max\|a1\| は 3〜4% vs 4.5〜11%.立方体は θ とともに単調に悪化し板の直下で軸上の 3.4〜5 倍.**球は θ≈30° が軸上より均一**(φ340: 0.0193 → 0.0057.軸上のリング構造が崩れる)で「どこに置いてもそこそこ」.立方体の優位は軸上の 1 点だけ.**結果 ②**: 真下向き(板が背後=バッフル無し)は板向き+バッフルと同等で 5〜30% 明るい.壁法線向き(キャビティ中心向き)は最悪(2〜5 倍).**結果 ③**: 対向 2 灯で m=1 は ≤0.3% に消え構造 CoV は 0.005〜0.010=単灯軸上より均一で形状差が消える.立方体は N=3 で崩れる(3 回対称が 4 回対称の壁と噛み合わない).**ノイズフロア**: 構造 CoV ±0.0007・a1 ±0.08%.設計への含意は「単灯なら球,多灯にできるなら側壁の対向 2〜4 灯・真下向き・バッフル無しで立方体でも球と同等」.**方法論**: 極角 θ を両形状共通のパラメータにし,立方体の稜(45°)は外す.板の近くのバッフルは外殻の貫通を許容し食い込み量を記録(壁法線向きは半径がキャビティ寸法の 0.6 を超えたら無効).解析は TEST_16/17 の方位フーリエ(m=1〜4)+構造 CoV+重心.**追加実験(同日夜)**: ① 方位角: 立方体は面の中央が最良で稜へ寄せるほど構造 CoV が 1.3〜1.75 倍に悪化(球は方位に依らない)/ ② 真下向き多灯(バッフル無し): 2 灯以上で非対称は消え単灯軸上より均一だが,板向き+バッフルの多灯には 1.5〜2.5 倍劣り N を増やしても頭打ち(一次照射が壁の下半分に集中し動径構造が残る).③ 校正材質(純 diffuse ρ=0.81)で主要 60 条件を引き直し: 配置依存の幅は球 0.030 vs 立方体 0.077〜0.098 と結論は不変(むしろ差が広がる).ただし旧材質の光沢 5% が作っていた軸上のリング構造が消え,**校正材質では両形状とも軸上が最良**(「球は θ≈30° が最良」は旧材質の産物).全 255 + 60 条件(TEST_18 結果 5〜7).**失敗パターン**: spawn のワーカーには主プロセスで切り替えた出力ディレクトリ(材質)が伝わらず,旧材質の row.json を再利用して 60 条件が空振りした → 材質を run_job の引数で渡す. - **正規化と最小/最大比の定義の見直し — 画像全体・ノイズ補正付きの min/max 比を指標に追加 (2026-09-14)**: ユーザー指摘「輪帯ピーク正規化は同心円状でない分布に向かない」から,輝度マップの正規化と min/max 比の定義を軸上スイープ(TEST_15 球 10・TEST_16 立方体 10)で系統的に比べた(`scripts/build_normalization_comparison.py`・`build_minmax_definition_comparison.py`・`build_fullimage_minmax.py`,出力 `output/_normalization_comparison/`).**発見**: ① 表示の正規化は対称な分布なら輪帯ピークとロバスト最大(平滑化後 99 パーセンタイル)が 1% 以内で同じ.非対称では輪帯ピークが破綻するので表示は後者に統一 / ② min/max 比は「最小」側がノイズの裾に敏感で,平滑化後のパーセンタイルは大きいキャビティ(生輝度が低くノイズ 26%)で 0.91〜0.92 に頭打ち.輪帯平均は数千画素の平均でノイズに勝つが方位を平均する / ③ 画像全体で使える定義 7 候補のうち「σ=12 平滑化の min/max をノイズ場(残差の空間シャッフル)の極値で補正」が対称分布で輪帯平均と ±0.01 で一致しノイズ床 ±0.004 と最良.ブロック平均は粗さと床のトレードオフ,多項式フィットは形を追えない.**実装**: `/implement` で `evaluation/fullimage.py` と `MetricsConfig.fullimage_min_max` を追加(既定 False.TEST_18 の評価 YAML で有効化).TEST_18 に適用すると輪帯平均は非対称条件で 0.97〜0.99 に張り付き,新指標は球 0.87〜0.91・立方体 0.65 まで下がる(差と \|a1\| の相関 0.93〜0.95).TEST_18 の全結果表と輝度マップパネルに min(最大=1 のときの最小値)を併記.**注意(テスターの指摘)**: 平滑化で真値より均一寄りに出る(線形勾配で +0.013)・ノイズ床はノイズ量に比例(相対 20% で 0.012)ため,σ と spp を揃えた条件間比較に使う.球のサイズ表記は内径 φ に統一(TEST_18 の文書・図.条件名は半径のまま). + +- **TEST_19 spp と計算時間・ノイズ・指標の安定性 (2026-09-14)**: ユーザー発案「GPU で速くなったので spp を上げてノイズと計算時間の関係を測りたい.全体のうち GPU が何秒かも知りたい」.TEST_18 の 6 条件を spp 256〜8192 × seed 2 で回し,段階別の壁時計(`mi.render` は `dr.sync_thread` で同期)を記録した.**結果**: GPU 時間は spp に厳密に比例(1024 で 5.1 秒),CPU 側の固定費は 0.8 秒で一定(PLY 書き出し・評価・保存)=spp ≥ 1024 で 1 割以下なので CPU 側の最適化はここまで.ノイズは全条件で 1/√spp 則に ±2% で一致(レンダ側に別のノイズ源は無い.ノイズ量は生の輝度で決まり,オフ軸は軸上の 1.5 倍).構造 CoV は 1024 で安定(8192 との差 ≤0.002)だが,画像全体 min/max 比は暗い大キャビティで 1024 だと 0.01〜0.02 過小評価で 2048〜4096 で収束.補正なしの平滑化 min/max は 8192 でも収束せず,輪帯平均 min/max は spp では改善しない(方位平均の問題).**推奨**: 構造 CoV の実験は 1024 のまま,min/max 比を暗い条件まで比べるなら 2048〜4096.**失敗パターン**: ① `--only scripts` の push では新しい src モジュール(fullimage.py)が無くて落ちた → 全体を push / ② サンプラー再起動の `pkill -f` が自分自身を殺して nvidia-smi の記録が残らなかった(結論には影響なし).16384 はユーザー都合で未実施.