目次/第01章
「作る」と「読み込む」はどう違うのか
procedural generation — 手続き的生成
- ふつうの3Dは、誰かが作ったモデルファイルを読み込んで表示します。
- このプロジェクトは逆で、実行した瞬間に座標も模様も計算で作ります。これを手続き的生成といいます。
- だから1個ずつ形が違い、焼き加減をあとから変えられ、しかもデータが軽い。
ゲームや映画に出てくる料理の3Dは、ふつう誰かが専用ソフトで作ったモデルファイルを読み込んで表示します。 ファイルの中には「頂点1番は(3.2, 1.1, 0.4)」といった座標が何万個も保存されていて、 表面の模様も写真として一緒に入っています。プログラムはそれを並べて画面に出すだけです。
このプロジェクトは逆のことをしています。ファイルも写真も読まず、 プログラムを実行した瞬間に座標を計算で作り、模様も1ピクセルずつ計算で描く。 これを手続き的生成(プロシージャル生成)と呼びます。 食べ物と相性がよく、いいことが3つあります。
- 1個も同じにならない — 数値を少し揺らすだけで、形の違う個体がいくらでも出てきます。 たこ焼き8個が全部同じ形だと、その瞬間に嘘に見えます。
- あとから変えられる — 「もう少し焼く」がスライダー1本で通ります。 写真を貼る方式なら、焼き加減の数だけ写真を用意することになります。
- 軽い — 14本ぜんぶ合わせて 1.5MB ほどのテキストだけです。 モデルファイルも、模様の写真も、1枚もありません。
その代わり、形や色を言葉ではなく数式で説明できないと作れません。 「たこ焼きってどんな形?」に 「下半分は型の写しでほぼ正確な半球、上半分は生地を折り込んだ不定形」と 答えられるかどうかが勝負になります。だからこのプロジェクトのコードは、 コメントの半分が食べ物の観察記録です。
ほとんどのファイルが、同じ9層でできている
トーストもクッキーも秋刀魚も、ファイルの構造はほとんど同じです。上から順に読めば、 どの料理でも同じ場所に同じ役割のコードがあります。 このサイトの第I部(01〜11章)は、この層に対応させてあります。
// 構成:
// 0. CONFIG … プリセット(定番 / 全部のせ / 焦がし / 塩)と舟皿
// 1. Rng … シード付き擬似乱数
// 2. Noise … 3D値ノイズ / 2D周期ノイズ
// 3. Mesh utils … 巻き順の自動判定・法線の溶接・掃引
// 4. Fields … 球面方向の場 / 焼き色 / ソースの垂れの輪郭
// 5. TextureLab … 生地・ソース・木のアルベド / ORM / 法線
// 6. Pattern … 形状 + テクスチャ(4種のアトラス)
// 7. Takoyaki … 生地玉 + ソース + 青のり + マヨ + かつお節
// 8. Tray … 経木の舟皿 + 板の間 / 配置の緩和
// 9. Scene / GUI
層の順番には理由があります。下の層は上の層を知らなくても動くように積んであるからです。 乱数(1)はノイズ(2)を知らないし、ノイズは形(4)を知らない。 だから途中の1層だけ差し替えれば、別の料理になります。 それを実際にやったのが17章です。
この教材には姉妹編(やさいのつくりかた)があり、そちらでは 4. Profile(横顔の折れ線)が形の中心にありました。 料理では、そこが 4. Fields や 4. Section という名前に変わっているファイルが多い。 野菜は「軸のまわりに回せば作れる」ものが多いのに対し、 料理は切ってあったり、潰してあったり、垂れていたりして、 回転体ではないものが増えるためです。
「焼く」という工程が、そのままコードにある
野菜と料理のいちばん大きな違いはここです。料理には火が通っている。
その結果として、表面の色が場所ごとに違い、水分が飛び、艶が出て、形が変わる。
14本のうち9本は、焼いたり揚げたりしたものです。その9本には例外なく
bake(焼き加減)・heat(熱の回り)・char(焦げ)
という名前の変数があります。
焼き色は最後に上から塗る飾りではなく、形と一緒に決まるものです。
それを扱うのが12章です。
- トースト.js の先頭のコメント(構成 0〜9)を読んで、他のファイルにも同じ並びがあるか確かめる。
- 手続き的生成のいいところ3つを、自分の言葉で1行ずつ書いてみる。
- 14本のファイルを検索して、bake / heat / char という語がどのファイルに出てくるか調べ、「焼いた料理」と一致するか確かめる。
- 身のまわりの食べ物で「数式で説明できそうな形」を3つ探す(例:バウムクーヘン、マカロニ、板チョコ)。