[Astro] #187 トップページの世界に風・雪・夜を足す 02 — ライトを目で見て決め、VR にも雪を降らせる
はじめに
前回は、トップページの世界に、風・雪・夜・スポットライトを足しました。風と雪は良い見た目になりましたが、夜とスポットライトは、仕組みだけで、見た目が決まっていませんでした。
[Astro] #185 トップページの世界に風・雪・夜を足す 01 — 髪・霧・雪を 1 つの風でつなぎ、調整パネルで決める
トップページの 3D の世界に、風、雪、時間帯(夜)、スポットライトを足した 1 回目の記録です。
lain-lab.com今回は、その続きです。この日にやったことは、次のとおりです。
- 調整パネルの値が、再読み込みで消えないようにする
- スポットライトの位置と向きを、画面の中で見えるようにする
- 床の高さのずれを、調整できるようにする
- 設定値を、コードの中から、JSON に移す
- VR でも、雪を降らせる
- 風と雪の出方に、ランダムを入れる
結論から言うと、ライティングは、かなり良くなりました。 決め手は、数字を変えることではなく、ライトの向きを目で見えるようにしたことでした。
調整パネルの値を、残す
前回、パネルの値は「記憶しない」作りにしました。気に入った値は、COPY で JSON に残す、という考えです。ところが、実際に使うと、不便でした。再読み込みするたびに、値が戻ります。開発サーバーが再読み込みされるだけでも、戻ります。
そこで、ブラウザの localStorage に、パネルの値を保存するようにしました。
- スライダーを動かすたびに、保存します
weather.jsonの初期値が変わったら、保存した値は捨てます。保存した値が、新しい JSON を、いつまでも上書きするのを防ぐためです。初期値から作った署名を、一緒に保存して、比べています- パネルの
RESETで、保存した値を消して、JSON の値に戻せます - 復元できたかどうかは、パネルの状態表示に出します
保存してはいけない値がありました
最初の版は、全部の値を保存していました。その結果、再読み込みしたら、風・雪・昼夜が、右クリックメニューで OFF になっていました。メニューのスイッチ(enabled)まで、保存していたからです。
メニューのスイッチは、「再読み込みで JSON の設定に戻る」と、前回決めていました。そこで、enabled、ランダムの ON/OFF(autoOn)、時刻の固定(override)は、保存しない値にしました。
保存したあと、復元の結果が見えなかったので、気づくのが遅れました。状態表示は、この件のあとで足しました。
スポットライトを、見えるようにする
前回の最後で、アバターを照らす光が、思うように当たりませんでした。調整パネルで、位置を動かしていると、こう言われました。
スポットライトというかポイントライト? Y を 0.5 にすると、頭だけ光るね
スポットライトの、向き・広がり・位置が、画面からは、分かりません。数字を変えて、結果を見て、また変える。当てずっぽうです。
以前、Three.js を勉強し始めたころにも、同じ思いをしていたそうです。ライトの位置と角度が見えないから、あてずっぽうで触るしかない。そこで、ライトを描くことにしました。
ワイヤーフレームで描く
- ライトの位置に、印を置きます
- ライトから、照らす点へ向けて、円錐(広がり)を、線で描きます
- 円錐の中に、もう 1 つ、内側の円を描きます(
penumbra、ぼかしの境界) - 長さは、ライトから、照らす点までの距離です
- VR / MR の中では、出しません
パネルに、LIGHT_SHAPE のチェックを足して、表示を切り替えられます。ライトは、アバターの子として置いているので、アバターが動くと、ワイヤーフレームもついてきます。
上から見た図と、横から見た図
ワイヤーフレームを入れても、まだ分かりにくい、と言われました。
近いので、感覚的には理解できない部分もあるね。ライトの光源が画面外にあるので、何となくは分かるけど
ライトは、画面の外にあります。カメラの前にいるアバターの近くでは、円錐の全体が、見えません。
そこで、パネルの中に、上から見た図と、横から見た図を、小さな絵で足しました。アバターを真ん中に置いて、ライトの位置、円錐の広がり、床の高さを、2 次元で描きます。カメラの位置に関係なく、ライトの関係が見えます。
(画像: 調整パネルの、上から見た図と、横から見た図)
床が、浮いていました
図を描くと、別の問題が見えました。床の光だまりが、床から浮いているのです。
前回、床には、疑似の光だまり(光の円)を重ねました。その高さの値(poolY)を、-0.5 まで動かせるようにしていましたが、足りませんでした。
原因は、このサイトの作りでした。最初に作ったステージの原点が、床ではなく、かなり下にあります。初心者のころに作ったからです。その原点に合わせて、VRM の座標を、下げて設計してありました。今ならこうはしませんが、直すのは面倒なので、そのままです。
直さずに、poolY のスライダーの範囲を、-3 から 1 まで広げました。これで、床に合わせられます。
見た目が決まった
ワイヤーフレームと 2 つの図で、ライトの向きが見えるようになると、調整が一気に進みました。
- ライトは、上から照らしたほうが、自然でした
- 色は、白でした
これだわ。ライトは上から照らした方が自然で、ライトの色は白だよ。というか、調整すると凄い良くなる。おしゃれ。これはインスペクターなしでは調整無理だよ。今後はライトを作る時、必須だね
前回の「全然だめ」から、見違えるようになりました。実機では、「ライティングが酷かったけど、かなり良くなった」と、確認できました。
(画像: ライティングを調整した、トップページ)
設定値は、JSON に書く
パネルで決めた値は、どこに置くか。ここで、次の問題が出ました。
スポットライトの値が、コードの中に、初期値として書いてあったのです。そして、その初期値は、かなり良くない見た目でした。JSON に値がないと、コードの値が使われます。
JSON に書いた方が良いよ、ハードコードは良くない
そのとおりです。値が 2 か所にあると、どちらが効いているのか、分からなくなります。
- 値は、
weather.jsonのtime.spotに、すべて書くようにしました - コード側の初期値は、何も起きない値に変えました。スポットは OFF、強さ 0、光だまりも OFF。JSON が読めなかったときに、見た目が壊れず、何も起きない側に倒れます
JSON のどこに貼るか
もう 1 つ、ここでも、詰まりました。パネルの COPY で出した spot のブロックを、weather.json の、いちばん外側に貼られました。コードは、time.spot の中しか読まないので、何も起きませんでした。
COPY の貼り先は、パネルの見出しに合わせて、TIME COPY なら time のブロックごと、という決まりを、はっきり示すことにしました。COPY の出力に、貼り先が分かる形をつける案は、まだ入れていません。
VR でも、雪を降らせる
前回は、VR / MR で、雪・霧・時間帯を、出さない作りにしました。ところが、Quest で見てみると、雪は、VR で見てこそ、でした。
VR でも雪、見たいね。昔実装した時は、雨を降らせてたけど、雰囲気が出る。ただ、広範囲だと数が増えるけど…
数が増えると、VR では重くなります。そこで、VR では、雪の量を、減らすことにしました。
- JSON に、
xrAmount(VR での雪の量の倍率)を足しました。今の値は 0.5 で、VR では半分の量です - VR では、カメラが、左右の目に 1 つずつあります。粒の大きさは、目ごとの画面の大きさと、投影の行列から、計算し直しています
実機では、「雪は良い。VR で見ると、雰囲気が良くなる」と、確認できました。
検証が、いつものやり方では、できませんでした
ヘッドレスのブラウザで確かめるとき、VR 中の状態を作ろうとして、「VR 中」と見せかけました。すると、描画のループ自体が止まりました。React Three Fiber は、VR 中は、通常の描画ループを止めて、VR 用のループに任せるからです。検証用には、フレームを手動で進める方法に、変えました。
霧は、VR で出していません
霧も、VR で見たくなりますが、霧は、重い処理です。半径の違う球の殻を、ノイズで描いています。VR で出すなら、軽い版を、先に作る必要があります。今回は、見送りました。
風と雪に、ランダムを入れる
VR で雪を見ていると、別の違和感が出ました。
ランダム要素がいるね。今は 100% 完全に出てるので
風も雪も、出ているときは、いつも同じ強さです。霧には、前から、時間で変わる仕組み(auto)がありました。同じ形を、風と雪にも入れました。
- 天候の名前ごとに、出る重みを決めます
- 名前ごとに、強さの倍率を決めます
- 抽選の間隔(分)と、変わるまでの時間(秒)を決めます
- 抽選のたびに、重みに従って、次の天候を選びます。強さは、変わる時間をかけて、なめらかに変わります
「雪のランダムは、粒のばらつきですか。それとも、出るか出ないかですか」と聞かれました。出るか出ないか、と、その量です。粒の位置や揺れのばらつきは、前回から入っています。
右クリックのメニューで、風・雪の auto を ON/OFF できます。パネルには、今の天候と倍率が出ます。
実装は、風・雪・霧で、抽選の部品(autoLevel)を、共有しました。設定が壊れていたら、倍率 1(何もしない)に倒れるように、しています。
auto の置き場所に、注意
置き場所は、少しややこしくなりました。
- 霧の
autoは、JSON の、いちばん外側にあります - 風の
autoは、windの中にあります - 雪の
autoは、snowの中にあります
実際、雪の値を貼るときに、霧の auto を、雪の値で上書きされました。同じ名前で、場所が違います。JSON を直して、置き場所を、docs に書きました。
詰まったこと
- 保存する値を、全部保存して、スイッチまで保存していました。再読み込みで、風・雪・昼夜が OFF になりました
- COPY の貼り先を、間違えられました。外側に貼られた値は、読まれません
- 初期値を、コードに書いていました。見た目が悪い値が、JSON に値がないときに、効いていました
- 床の原点は、初心者のころの設計の名残でした。直さずに、スライダーを広げました
autoが、霧は外側、風と雪は中、というつくりでした。上書きの事故が、起きました- VR 中の検証では、描画ループが止まります。フレームを、手動で進めて確かめました
未確認のこと・制限
- 処理の重さは、測っていません。VR の雪は、見た目では問題ありませんでした
- 床の高さの調整は、実機の見た目で決めました。モデルやステージを変えると、合わない可能性があります
- ライトのワイヤーフレームと、2 つの図は、Chrome(Windows)と、Quest のブラウザで確認しました。スマホは確認していません
- 霧は、VR で出していません。調整パネルにも、まだ入っていません
- ランダムの重みと倍率は、見た目で決めた値です。適切かどうかは、使いながら見ます
- 調整パネルは、localhost か
?tuneのときだけ出ます。見る人に公開するかは、決めていません - PC 側の Quest Link と Chrome では、WebXR が動かない問題が、未解決です。今回の VR の確認は、Quest 単体のブラウザで行いました
おわりに
前回、「光の調整は、自分の目で決める作業」と書きました。今回は、その目に、ライトの向きを見せることで、調整が進みました。ライトは、見えないから、当てずっぽうになります。見えれば、触れます。
Inspector を作り続けている理由と、同じです。中身が見えないものは、直せません。ライトを作るときは、これからも、まず見える道具を作ります。
次は、調整パネルを、見る人に公開するかどうかを、決めます。公開するなら、tune というコマンドと、ヘルプから、静かに使える形にするつもりです。そのあと、霧を VR で出す、軽い版を、試します。
PROTOCOL.LAIN // Archive
lain-lab.com のトップページ。右クリックメニューから、霧・風・雪・昼夜・ランダムを切り替えられます。
lain-lab.com