目次/第14章
透けないと、食べ物に見えない
subsurface scattering — 光が中に入って散る
- 団子の透けを切ると石膏に、赤身の透けを切ると赤く塗った消しゴムになります。
- 光は表面で全部はね返るのではなく、中に入って散ってから出てきます。
- 薄いところほど多く抜けるので、厚みの情報を持たせるのが要点です。
食べ物のほとんどは、多かれ少なかれ光を通します。 上新粉の生地、白玉、マグロの赤身、大根おろし、レモン、米粒、鮭の身。 光が表面で全部はね返るのは金属だけで、 食べ物ではいったん中に入り、何度か散らばってから、別のところから出てきます。 これを subsurface scattering(表面下散乱、SSS)といいます。
これが見た目にどう出るかというと、逆光になったときの縁です。 光を後ろから当てると、薄い部分だけが明るく透けます。 団子の輪郭がふわっと白く光り、赤身の縁が赤く抜ける。 料理写真が斜め後ろから光を当てるのは、これを見せるためです(→ 11章)。
実験 — 透けを切る / 光を後ろへ回す
透けを 0 にすると、光をどこから当てても縁が抜けません。
白玉が石膏に、赤身が消しゴムに見えるのはそのためです。
立体はドラッグで回せます(触ると自動回転は止まります。ダブルクリックで戻ります)。
光を後ろへ回してから立体も回すと、抜けて見える向きが探せます。
厚みを、どうやって知るか
「薄いところほど透ける」を実装するには、その点の厚みが必要です。 ところが3Dの表面には厚みの情報がありません。そこで、あらかじめ計算して テクスチャに焼いておきます。これを thickness テクスチャといいます。
// 3. TextureLab : 厚みを焼く(ご飯.js の米粒) // 米粒は中心が厚く、縁と両端が薄い。単純な形なら式で書ける const th = Math.sqrt(Math.max(0, 1 - rr)) * (1 - 0.35 * endFade); mat.subSurface.thicknessTexture = bake(th); mat.subSurface.isTranslucencyEnabled = true; mat.subSurface.translucencyIntensity = 0.45;
散る色は、素の色とは違う
中を通ってきた光は、素の色そのままでは出てきません。 赤身なら、より赤く、より暗く。白玉なら、わずかに黄味を帯びて。 だから SSS には、アルベドとは別に散乱の色(tint)を持たせます。
お寿司.js の赤身は、この色を [0.560, 0.088, 0.098](深い深紅)に取っています。
表面の色より濃い。「光を通すと明るくなる」のではなく、
光を通すと、その材質の色が濃く出るのが正しい方向です。
切り身は「表面」ではなく「切り口」
お寿司.js のコメントに、この章と関係の深い一節があります。
野菜の皮や、たこ焼きの生地は外側です。ところが刺身や鮭の切り身は、 内部構造がむき出しになっています。だから模様の作り方が変わります。 筋肉の束(筋節)が斜めに走る場を作り、それを切った断面を模様にする。 鮭の白い筋(ミオコンマ)が「く」の字に並ぶのは、そのためです。
霜降りは色ではなく実体です。 アルベドに白い線を描いただけだと、印刷したステッカーになります。 脂は肉より白く、やわらかく、わずかに盛り上がって光る。 法線と粗さも一緒に変えないと霜降りになりません。
透けを強くしすぎると、光る風船になります。 subSurface は「ぼんやり光る」ので、上げるほど良く見えがちです。 14本のサンプルの値は、身のあるもので 0.4〜0.7(赤身 0.55 / 中トロ 0.62 / 大トロ 0.70、 団子は白玉 0.52 / 桜 0.55 / 白 0.62、ご飯 0.45)。削り節やひれのように「透けて当然」の薄いものでも 0.85 止まりで、 1.0 に近い値はどこにもありません。
- 「白玉」で透けを 0 にして、何に見えるか言葉にする。
- 光の向きを 160°(真後ろ)にして、透けの有無を見比べる。
- 「赤身」で透けを 1.0 にすると、どこから食べ物でなくなるか探す。
- お寿司.js で「透」を検索し、赤身・中トロ・大トロで値がどう違うか比べる。