ブドウ
https://playground.babylonjs.com/#86KHSI#11 … Claude Opus 5
https://scrapbox.io/files/6a6436d6c66da3b7e884d8ab.png
https://playground.babylonjs.com/#86KHSI#1 … Claude
https://scrapbox.io/files/671ecd6a5543685ec7d86cdc.png
https://playground.babylonjs.com/#86KHSI#5 … Claude Opus 4.6
https://scrapbox.io/files/69db1a4e3caed06dfe75172e.png
https://playground.babylonjs.com/#86KHSI#4 … ChatGPT
https://scrapbox.io/files/69db19673caed06dfe751612.png
https://playground.babylonjs.com/#86KHSI#6 … ブドウシミュレータ
https://scrapbox.io/files/69db1d3b3caed06dfe751bb7.png
https://playground.babylonjs.com/#86KHSI#8 … Claude Fable 5
https://scrapbox.io/files/6a2c459874d67ad5aef9cc1d.png
プロンプト
Babylon.jsを使って、自然なブドウの房を3Dで生成したいです。以下の要件を満たすコードを作成してください:
要件:
1. ブドウの形状
- 上から下に向かって広がる円錐形の房
- ブドウの粒は球体で表現
- ブドウの粒のサイズはやや不均一
- 自然な不規則性のある配置
2. 材質と見た目
- ブドウの粒はPBRマテリアルで紫色
- 光沢感と半透明効果
- 枝は茶色で自然な質感
3. 構造
- メインの枝から小枝が分岐
- 各ブドウの粒は小枝で接続
- 層状に配置されるが不規則性あり
4. カスタマイズ可能なパラメータ
- 房の大きさ
- 層の数
- ブドウの密度
技術的な詳細:
- Babylon.jsのMeshBuilder、PBRMaterial、ベジェ曲線を使用
- クラスベースの実装
- 再利用可能なコード構造
コードはBabylon.js Playgroundで動作する形式でお願いします。
プロンプト強化版
依頼:Babylon.js Playground で「写実的なブドウの房」を生成する
あなたは Babylon.js のシニアグラフィックスエンジニア兼、果実の質感表現に詳しいルックデブ担当です。
以下の仕様を満たす 単一の Playground コード を作成してください。
「球を紫にして並べただけ」の出力は不合格です。写真と並べて違和感がないレベルを狙います。
0. 出力形式(厳守)
var createScene = function () { ... return scene; }; の形式。TypeScript 不可、外部 npm 不可。
外部アセットは https://assets.babylonjs.com/ 配下のみ(HDR 環境テクスチャ等)。それ以外の URL は使わない。
テクスチャ画像は使わず、NoiseProceduralTexture / DynamicTexture で手続き的に生成する。
コード冒頭に const CONFIG = {...} を置き、後述のパラメータを全てそこに集約する。
クラス設計:GrapeCluster(房全体の統括)/ Rachis(果梗=軸と枝)/ BerryFactory(粒の生成とマテリアル)/ Rng(シード付き乱数)に分割。
各ブロックの冒頭に「何をしているか」の日本語コメントを入れる。
1. 房の構造(植物学的に正しく)
単純な円錐配置は禁止。実物の果房構造をモデル化すること。
主軸(rachis):Curve3.CreateCatmullRomSpline で緩く湾曲した垂下曲線を作り、MeshBuilder.CreateTube の radiusFunction で基部→先端に向けてテーパーさせる(先端で 0 にせず最小値でクランプ)。
一次側枝(branch):主軸に沿って螺旋葉序的に(黄金角 ≒137.5° ± 揺らぎ)分岐させる。上部ほど長く、下部ほど短い → 結果として逆円錐+肩の張りが自然に生じる。
肩(shoulder)と翼(wing):最上部の 1〜2 本の側枝だけを著しく長くし、独立した小房(翼)を作れるようにする(CONFIG.wingProbability)。
果梗(pedicel):各粒は 3〜8mm 相当の短い小梗で枝に接続。粒の中心ではなく 粒表面から半径×0.85 の位置まで挿し込む(浮き・貫通防止)。
垂れ下がり:粒の重量で枝先が下方向に曲がる。枝終端の接線を重力方向へ lerp する簡易サグを入れる。
軸の質感:基部は木質化(暗褐色・粗い)、先端は緑がかる。頂点カラーまたは高さ依存のグラデーションで表現。
任意で**巻きひげ(tendril)**をヘリカルパスの Tube で 1〜2 本追加。
2. 粒(berry)の形状
真球禁止。扁球〜卵形(長短径比 0.88〜1.05 をランダム)にスケール。
へそ:果梗接続部を頂点操作でわずかに凹ませる。
花柱痕:反対極に微小な突起または暗いスポットを残す(テクスチャで可)。
相互圧迫による変形:隣接粒が多い個体は接触方向にわずかに扁平化させる。
サイズ勾配:房の下部・内側の粒は 10〜20% 小さい。日陰側は着色が浅い。
向き:果梗軸を基準に Quaternion.FromUnitVectorsToRef で整列させ、そこへ ±15° のランダム傾きと軸周りランダム回転を加える。
粒は 16〜24 分割の球をベースに、法線再計算(createNormals / ComputeNormals)を必ず行う。
3. マテリアル(ここが写実性の分かれ目)
PBRMaterial を使用し、以下を すべて 設定すること。
サブサーフェス透過:subSurface.isTranslucencyEnabled = true、tintColor に果肉色(赤紫〜赤)、translucencyIntensity 0.7〜1.0、minimumThickness / maximumThickness を粒径に合わせる。逆光で果実の内部が透ける状態を目標にする。
屈折:subSurface.isRefractionEnabled = true、indexOfRefraction ≒ 1.35(バージョンにより pbr.indexOfRefraction)。
クリアコート(果皮のロウ層):clearCoat.isEnabled = true、clearCoat.roughness 0.05〜0.15。ハイライトが二重になる(拡散した本体反射+鋭い表面反射)ことを確認する。
ブルーム(果粉):ここを最重要とする。以下いずれかで実装し、選んだ理由をコメントに書くこと。
(A) 粒メッシュを 1.01 倍した薄い外殻を重ね、albedo 灰白・roughness 1.0・metallic 0・弱い alpha で覆う。
(B) NoiseProceduralTexture を roughness/albedo に混ぜ、上向き面ほど白濁、接触部・下面ほど擦れて薄くする。
どちらでも ムラ(指で触れた跡のような不均一) を必ず入れる。均一な白濁は不自然。
色バリエーション:単一の紫を全粒に使わない。HSV でヒューを ±、明度を粒ごとに変え、未熟粒(緑〜淡赤)を 2〜5% 混ぜる。
微細凹凸:ノイズベースの弱いバンプで、鏡面ハイライトを不均一にする。
4. ライティングとポストプロセス(省略不可)
CubeTexture.CreateFromPrefilteredData で .env の IBL を設定(未設定だと PBR が破綻する)。
主光源+リムライト(逆光)を配置し、サブサーフェス透過が見える構図にする。
ShadowGenerator(PCF またはブラー付き ESM)で房の内部に自己遮蔽の影を落とす。
SSAO2RenderingPipeline を必ず有効化。粒と粒の接触部の暗がりが無いと「団子」に見える。
DefaultRenderingPipeline:FXAA/MSAA、控えめな Bloom、任意で被写界深度。
imageProcessingConfiguration:ACES トーンマッピング有効、exposure / contrast を調整して紫の飽和を防ぐ。
ArcRotateCamera を房が画面いっぱいに収まる位置に配置し、wheelPrecision を調整。
5. 配置アルゴリズム
シード付き擬似乱数(mulberry32 等) を実装し、CONFIG.seed で完全再現可能にする。Math.random() は使用禁止。
粒の配置は「生成 → 重なり解消のリラクゼーション(数十回反復で中心間距離が半径和以上になるまで押し出す)」の 2 段階。めり込みゼロを保証する。
押し出し後に果梗の始点・終点を再計算する(順序を逆にすると梗がずれる)。
6. パラメータ(CONFIG)
seed / clusterHeight / clusterWidth / berryCountTarget / berryRadius と分散 / density(詰まり具合)/ sag(垂れ)/ wingProbability / bloomStrength(果粉の濃さ)/ ripeness(着色の進み)/ varietyPreset
品種プリセットを 3 種用意(例:巨峰=大粒・濃紫・果粉強、シャインマスカット=黄緑・果粉弱・楕円、ピノ・ノワール=小粒・超密着・肩張り)。プリセット切替だけで見た目が明確に変わること。
7. パフォーマンス
粒は 1 つのソースメッシュ+ InstancedMesh または thin instance。個体色差は registerInstancedBuffer("color", 4) または thinInstanceSetBuffer("color", ...) で与える。
目標:粒 300 個で 60fps。
8. 既知の失敗パターンと必須の対策(事前に潰すこと)
1. 真球+均一な紫 → プラスチックのおもちゃ。扁球・へそ・花柱痕・色ムラ・果粉で回避。
2. 半透明を alpha ブレンドで表現 → 描画順が破綻し影も落ちない。alpha は使わず subSurface の translucency/refraction で表現し、不透明パスを維持する。果粉外殻に alpha を使う場合のみ、needDepthPrePass と描画順を明示的に管理する。
3. 環境テクスチャ未設定 → PBR が真っ黒/のっぺり。IBL は必須。
4. トーンマッピング無し → 紫が飽和して単色の塊になる。ACES +露出調整。
5. AO / 接触影が無い → 粒の境界が消えて団子状に見える。SSAO2 必須。
6. 粒のめり込み → 配置後のリラクゼーションで解消。
7. 果梗の浮き・貫通 → 粒表面より内側(半径×0.85)まで挿す。
8. 完全な円錐シルエット → 肩・翼・下部の細りを入れる。
9. radiusFunction が 0 を返す → NaN や描画崩れ。最小半径をクランプ。
10. PrePass 系(SSS 散乱)と SSAO2 / DefaultRenderingPipeline の併用 → 競合して真っ黒や描画抜けが起きる。有効化順序を明示し、競合したら translucency 側で代替する。
11. thin instance で元メッシュが二重に描画される → 可視性の扱いに注意。
12. 毎回見た目が変わる → シード固定 PRNG で再現性を担保。
13. 法線再計算忘れ → 変形させた粒の陰影が壊れる。
9. 受け入れ基準
Playground に貼って コンソールエラー 0 で即描画 される。
粒の相互貫通が視認できない。
逆光カメラ角度で果実内部の透過が確認できる。
果粉のムラとクリアコートの鋭いハイライトが両立している。
seed を変えると異なる房、同じ seed では同一の房になる。
品種プリセット 3 種が明確に描き分けられる。
10. 進め方
1. まず構造のみ(ワイヤーフレーム+灰色マテリアル)でシルエットと配置を成立させる。
2. 次にマテリアル、最後にライティング/ポストプロセス。
3. 完成コードの後に「実物と比べてまだ不足している要素」を 3 点、改善案付きで挙げること。
#作ってみた #Playground #autumn #Claude #果物