TL;DR

  • logcamera.com の露出シミュレーター を参考に、SS(シャッタースピード)・F値(絞り)・ISO の3パラメータをスライダーで動かす Vue ページを作った
  • 最初は「シャッタースピードを変えるだけで明るさが変わってしまう」挙動でユーザーが違和感を覚えた → 実は物理的には正しい(Mモード相当)が、初学者には何が原因で何が結果か分からなくなることに気づいた
  • 解決策として「効果を学ぶ」モードと「露出を学ぶ」モードの2モード切替を追加。前者は brightness を固定して各パラメータの効果(ボケ・ブレ・ノイズ)だけ観察できる
  • トップページのコンテンツ一覧の一番後ろに導線を追加した

きっかけ: ロカメラのシミュレーターが面白かった

朝、logcamera.com の露出シミュレーター を眺めていて、これは自分の Nuxt プロジェクトにも欲しいと思った。

3つのスライダー(F値・SS・ISO)を動かすと、プレビューがリアルタイムにボケたりブレたり、ノイズが乗ったりする。カメラを触ったことがない人でも「F値を開くと背景がボケる」「SS を遅くすると動く被写体がブレる」「ISO を上げるとザラつく」が一画面で体感できる。

似たものを自前で作って、トップページから辿れるようにしようと決めた。


実装1: 3スライダー + SVG プレビュー

apps/web/app/pages/exposure-simulator.vue を新規作成した。構成は次の通り。

  • 3スライダー: F値(1.4〜22)、SS(30秒〜1/4000秒)、ISO(100〜25600)
  • SVG プレビュー: 風景の上に「立っている人」と「走っている人」を並べる
    • F値を絞ると背景がシャープに、開くと背景にぼかしフィルタがかかる
    • SS を遅くすると 走っている人だけ モーションブラーが乗る(立っている人はシャープなまま)
    • ISO を上げるとプレビュー全体に SVG のノイズフィルタが乗る
  • 露出メーター: 3つの値から EV を計算して「-2EV(アンダー)/ 適正 / +2EV(オーバー)」を表示

立っている人と走っている人を並べたのは、SS の効果を分かりやすく見せたかったから。ロカメラのシミュレーターも同じ構図で、動く被写体だけがブレることが伝わるようになっていた。

dev サーバーを起動して開くと、最初のプレビューは真っ白だった。初期値のままだと露出オーバーで白飛びしていた。挙動としては物理的に正しいので、初期値を「晴天で適正露出になる組み合わせ」(F8、1/250秒、ISO100)に直した。

夜景・F1.4・1/15秒・ISO3200 に振ると、左の立っている人はシャープ、右の走者だけが大きくブレて流れる。参考にした logcamera.com と同じ「動く被写体だけブレる」表現になった。


バグ発覚: 「SS だけで明るさが変わる」のは間違いか?

完成したつもりで報告したら、ユーザーから指摘が入った。

シャッタースピードを変えるだけで、なんか光の露出が変わってるんですけど、これは間違ってませんかね。

最初は「バグかも」と思って計算式を見直そうとした。が、ここで踏みとどまって物理的な仕様を整理した。

EV の計算式

露出値 EV は次の式で決まる。

EV = log2(F² / SS) - log2(ISO / 100)
  • F値を絞る(数字を大きくする)→ EV が増える → 暗くなる
  • SS を速くする(1/4000秒など)→ EV が増える → 暗くなる
  • ISO を下げる(100など)→ EV が増える → 暗くなる

つまり SS だけを動かしても明るさは変わる。これがカメラのMモード(マニュアル)の挙動そのもので、参考のロカメラも同じ作りだった。

でも、初学者には何が原因か分からない

物理は正しい。ただ、シミュレーターの学習目的から考えると話が変わる。

「SS の効果を知りたい」だけの人がスライダーを動かすと、ブレ(SS 本来の効果)と明るさ(露出の合成結果)が同時に変わる。何が SS の効果で、何が露出の話なのか切り分けられない。

これは「3つを同時に動かして適正露出にバランスする」というカメラ学習者向けの設計が、「個別効果だけ観察したい」入門者向けの設計と衝突しているということだった。


解決: 2モード切替

両方のニーズに応えるため、画面上部にトグルを追加して2モードを切り替えられるようにした。

モード1: 「効果を学ぶ」(brightness 固定)

  • プレビューの brightness は常に固定(自動で適正露出になる前提)
  • 露出メーターは隠す
  • F値 = 背景ボケ「だけ」が変わる
  • SS = 走者のブレ「だけ」が変わる
  • ISO = ノイズ「だけ」が変わる

これで「SS を 1/15秒まで遅くしても背景の空と地面の明るさは変わらず、走者だけがブレて流れる」という観察ができる。立っている人は変わらずシャープなまま。

モード2: 「露出を学ぶ」(Mモード相当)

  • 3つの値から EV を計算してプレビューの brightness に反映
  • 露出メーターを表示し、適正/オーバー/アンダーを示す
  • 「SS を速くしたら ISO を上げて補う」のような三角関係を体感できる

ユーザーの「明るさが変わるのはバグでは」という違和感は、設計レベルでは正しかった。物理を曲げるのではなく、学習目的ごとにモードを分けるのが正解だった。


トップページへの導線追加

実装が落ち着いたところで、ユーザーから次の指示。

トップページにもちゃんとあれですかね、物質シミュレーターみたいなやつでページ作ってくれてましたっけ? まだ作ってないか。じゃあこれ、コンテンツのところに入れといてもらえますか? 順番は一番後ろでいいです。

トップページ(apps/web/app/pages/index.vue)の「学習・クイズ」セクションの一番後ろにカードを追加した。タイトルは「カメラの露出シミュレーター」、リンク先は /exposure-simulator


できたもの

  • ページ: /exposure-simulator
  • ソース: apps/web/app/pages/exposure-simulator.vue(新規 / 719行)
  • コミット: ab4d8029 feat(exposure-simulator): F値/SS/ISOの3要素シミュレーターを追加

スライダーを動かすと、SVG の風景の上で走者だけがブレ、背景がボケ、全体にノイズが乗る。「効果を学ぶ」モードでは brightness が固定で各パラメータの効果が単独で見える。「露出を学ぶ」モードでは EV メーターが動いて、3つの値のバランスを意識する練習ができる。


学び: 物理的に正しい != 学習者にとって分かりやすい

カメラのシミュレーターを作っていて、いちばん勉強になったのは、「物理的に正しい挙動」と「学習者にとって理解しやすい挙動」が別物だったことだった。

  • バグとして指摘されたが、計算式を直すべきだったわけではない
  • 直すべきは情報の見せ方で、目的ごとに UI を分ければ両立する
  • 「Mモードでカメラを操作する人」と「SS の効果だけ知りたい初心者」は、同じ画面では満足できない

このパターンは、シミュレーター以外でも応用が効きそう。複数の変数が絡む現象を可視化するとき、「全部同時に動かす」モードと「1つずつ動かす」モードの両方を用意すると、学習者が因果を追える画面になる。


関連