もどる

2026-07-12 ・ 最終更新 2026-07-20

ゆとり

焚き火を眺めて過ごすためのWebサイト。動画ではなく、炎も火の粉も星空もすべてその場で計算して描いています。最初は「かなりちゃちで残念」な出来でしたが、炎の重なりを光として足し合わせる・薪をきれいに並べるのをやめる、という2つの直しで本物に近づきました。

開く

背景

焚き火を眺めているときの、あの何もしていない時間が好きです。炎の揺れを見ているだけで頭の中が静かになっていきます。

それを画面の中でも味わえないか、と思って作り始めたのが「ゆとり」です。パチパチという音、立ちのぼる火の粉、ゆっくり動いていく星、時間とともに移り変わる空。焚き火のある場所を丸ごと再現することを目指しています。

名前は、将来この上でAIと対話できるようにしたときに、対話アプリ「はく」と合わせて「よ・はく(余白)」になるところから来ています。

つくり方の方針

最初に決めたのは、動画を使わずコードで生成するということでした。

焚き火の映像を流すだけなら簡単です。ただそれだと、星が時間とともに動くことも、火を強くしたり弱くしたりすることも、朝から夜へ移り変わることもできません。炎も火の粉も星空も、すべてその場で計算して描くことにしました。

炎の形を決めるにあたっては、参考にする焚き火の動画を数本用意して、まずGeminiに観察させました。揺れの周期は何ヘルツか、色はどう変化するか、火の粉はどれくらいの速さで昇るかを数値で書き出してもらい、それをもとに実装しています。映像を見て言語化するのはGeminiに任せ、それをコードに翻訳するのは自分とClaudeでやるという分担です。

面白かったのは、3本の動画の分析結果が同じ構造に収束したことでした。ゆっくりしたうねりと細かいちらつきが重なり、温度によって色が変わる。共通していた部分がそのまま実装の骨格になり、違っていた部分がパラメータの範囲になりました。

「かなりちゃちで残念」からの作り直し

最初に動くものができたとき、正直がっかりしました。炎らしきものは揺れているのですが、頭の中にあったイメージとは似ても似つかない代物だったのです。

そこから改善を重ねました。効いた順に書きます。

1. 炎を部分的に透明にしたこと。 これが圧倒的に効きました。それまでは炎の板が何枚か重なって「紙を切り抜いて貼った」ように見えていました。炎は光を発しているのだから、重なったところは隠すのではなく足し合わせるべきなのです。合成の方法を変えただけで、切り絵が光のグラデーションになりました。

2. 薪をきれいに並べるのをやめたこと。 それまで薪は円錐形にきちんと組んでありました。整いすぎていて機械的に見えるのです。参考写真の薪の位置を1本ずつ写し取って、乱雑に積んだ配置に置き換えました。これで一気に本物らしくなりました。

どちらも、パラメータをいじって近づけようとしていた間はまったく届かなかった改善です。「物理的に何が起きているのか」「人は何を機械的だと感じるのか」に立ち返って初めて解けました。

その後も、陽炎、煙、星の残像、熾火と作り込みを続けています。表面をつるつるからごつごつにする、影を落とす、火明かりを揺らす。ひとつずつ足すたびに、少しずつ焚き火に近づいています。

左から、作り始めたばかりの単純な炎・薪を整えて並べた状態・透明合成のバグで炎が板のように見えた瞬間・薪を乱雑にして自然になった状態・現在の状態

左から順に、作り始めた日(7/13)の試行錯誤から現在(7/17)まで。3枚目は透明合成がうまくいかず炎が板のように見えてしまった失敗も、記録としてそのまま載せています。

機能

  • 焚き火のシーン:炎・火の粉・煙・熾火・薪・地面・陽炎を、すべてその場で計算して描いています
  • 時刻の操作:スライダーで昼から夜まで自由に動かせます。空の色・太陽・星がすべて連動します
  • 星空:天球がゆっくり回り、長く見ていると星が残像の線を引きます
  • 火の強さ・風・煙の量:スライダーで調整できます
  • 背景シーン:森・草原・砂浜・湖・荒地から選べます
  • :焚き火の環境音に、パチパチという爆ぜる音をランダムに重ねています。火が強いほど頻繁に鳴ります

技術的なポイント

Next.js に Three.js(react-three-fiber)という構成です。

設計上いちばん大事にしたのは、シーンの状態をひとつのオブジェクトにまとめることでした。時刻・火の強さ・風・煙・音量・背景を、すべて1箇所で持っています。今はスライダーがこれを操作していますが、将来「火守り」のようなキャラクターと話せるようにしたとき、AIに操作させる対象がまったく同じになります。「火を強くして」「そろそろ夜にして」と話しかけるだけでシーンが変わる、という形にそのまま繋げられます。

音は、環境音のループの上にパチパチ音をランダムなタイミングで重ねる方式です。鳴る間隔・音の高さ・左右の位置を毎回変えているので、同じパターンの繰り返しに聞こえません。

学んだこと:確認した画像と実際の画面が違う

これがいちばんの収穫でした。

Claudeは自分で画面を撮影して確認できます。ところがその画像と、実際のブラウザで見える画面が食い違うことが何度かありました。

一度は、炎が「半透明の四角い板」として見える現象。検証用の画像では正常なのに、実際のMacのブラウザでだけ起きていました。原因は、検証環境がソフトウェアで描画しているのに対し、実機ではGPUとOSの画面合成を通るため、経路が違っていたことでした。

もう一度は、画面全体が真っ黒になる現象。しかもなぜか湖のシーンでだけ起きます。原因は、シェーダの中の計算がある特定の1行だけで数値として成立しない値になり、それが後処理でにじんで画面全体に広がっていた、というものでした。しかもその1行が現れるかどうかは、置いた場所によって変わります。

いずれも、自分がスクリーンショットを撮って「ここがおかしい」と伝えるまで発見されませんでした。AIの自動検証は速くて頼りになりますが、見ているものが本当に自分の見ているものと同じとは限らない。そこは人間が確認する必要があります。

現状

公開しました。草木を風で揺らすこと、流れ星、熾火の作り込みが残っています。

作りながら夢が広がっているところもあります。スマホ版にして、机の真ん中に置いて焚き火のように囲む。いつか立体のホログラムにする。最後のはデバイスから作る必要がありますが、それはそれで面白そうです。