記録 · 研究 / 実装 · 2026.09
Claude Code と作った three.js のサイト
Claude Code で three.js のサイトを2本つくって残った、確かめ方の線引き
three.js のサイトを Claude Code と2本つくった。いちばん効いた制約は、AI が画面を見られないことだった。何を機械に確かめさせ、何を自分の目に残すか。その線引きの記録。
ガラスを2回つくった
1本目はガラスアートのコレクティブのサイトで、画面全面をリブの入ったガラスが覆う。縦の筋に光が走り、読み進めると筋の奥の色が変わる。FBO に一度描いてから、屈折と色収差をかけたシェーダーで歪ませている。

2本目は自分のサイトで、中央に数式で描いたガラスの薔薇が咲く。こちらは three.js の物理マテリアルの透過を使っている。どちらもビルドツールを使わず、ES モジュールと importmap だけで組んだ。

コードは書けるが、絵は見られない
Claude Code は three.js のコードを書ける。マテリアルの値も、シェーダーも、スクロールとの同期も書ける。書けないのは判断のほうだ。出力した絵を見られないので、「ガラスに見えるか」を永久に判定できない。
逆に、機械のほうが正確な領域もある。構文が通るか。実行時に例外が出ないか。要素が何ピクセルの位置にあるか。横に溢れていないか。参照した画像が実在するか。人間が目視で数えるより速く、確実だ。
だから最初に決めたのは、機能の設計ではなく、この線をどこに引くかだった。

機械側は、毎回全部通す
渡す前に必ず3つを通す。HTML から script を抜き出して構文チェックにかける。ローカルサーバー経由で画面のないブラウザを起動し、コンソールに例外が出ていないか読む。スクリーンショットを撮る。ここまでで数十秒。
これで捕まえた不具合がある。時刻の計算が一瞬だけマイナスになり、負のインデックスで参照した要素が undefined になって、そこで例外が出てフレームループごと停止していた。画面上では「たまに動かない」としか見えない。コンソールに1行出ていれば5分で終わる話だった。
取り逃したものもある。構文チェックの抽出条件から <script type="module"> が漏れていて、モジュール側が長いあいだ未検査だった。しかも構文チェックは、定数を定義より前に使う類の誤りを検出しない。実際にそれが起きて、スクリプトが丸ごと停止し、一覧のカードが0件になっていた。構文が通ることと、動くことは別だ。
目の側で起きた事故
画面のないブラウザに幅390pxと指定しても、実際は最小幅500pxで組版され、390pxで切り取られた画像が返ってくる。溢れていないものを、溢れていると読んだ。
図版を1600pxで書き出したことがある。本文欄は576pxなので0.36倍に縮み、11.5pxの文字が4pxになった。構文も座標も画像の存在も、どの検査も通る。目で見れば一発で分かる。
いちばん悪かったのは、フレーム間の差分が大きいことを根拠に「アニメーションできている」と判断したときだ。実際には背景が一度も変わっていなかった。共通しているのは、機械が「異常なし」と言った領域を、目で見ずに信じたことだった。
ガラスだけは、毎回自分で見る
透過には落とし穴が多い。レンダラの背景を透過にすると、透過の計算が下地を失って破綻する。透過のバッファには不透明なオブジェクトしか入らないので、ガラス越しに見せたい板を透明にすると何も映らない。どちらもコンソールには何も出ない。「映らない」という結果でしか分からない。
そのうえ、画面のないブラウザでは確かめられない。GPU を使えば描けるが環境光が暗く、実物と色が違って見える。ソフトウェアの描画に切り替えると、透過の計算で事実上停止する。
だから薔薇の見え方だけは、毎回ブラウザを開いて自分で見た。ここは自動化しない、と決めて書いておく。書いておかないと、数値が良かった日に見なくなる。
残ったもの
2本つくって残ったのは、three.js のコードではなく、この線引きのほうだった。機械に任せる側は手順を固定して毎回全部走らせる。目に残す側は「ここは目で見る」と明記する。
線を引き直すのは、事故が起きたときだけでいい。