CommunityImagegithub.com

Procedural Cloth (No Simulation)

Procedurally 'design' photorealistic static cloth (without physics simulation): unmade quilts, blankets, tablecloths, fabric draping over bed/table edges, flipped-up corners, objects on cloth, and curtains hanging from rods (pleats from rings, falling and spreading fabric, tied hems, stitching, double-layered edges, linen weave).

What is Procedural Cloth (No Simulation)?

This skill provides a reusable, deterministic approach to creating static cloth geometry that looks like a real unmade bed, curtain, or draped fabric, all without any physics simulation. It works by defining a height field over a flat plane—composed of artistically placed lobes, directional folds, eroded peaks, and explicitly drawn creases—which is then wrapped onto a support object (like a mattress). The method then adds effects like folds toppling to one side, corner flips, UV relaxation based on the 3D surface (to prevent texture stretching), and fine wrinkle normal maps with cavity shading. The entire process takes under 0.5 seconds and is perfectly reproducible with the same seed. The skill includes a fully commented library (`scripts/cloth.js`), a staged example viewer (`example/index.html`), verification data, a separate curtain system (`scripts/curtain.js`) based on non-stretchable cross-section integration, and guidance (`references/engines.md`) for porting the output to Godot or Unreal Engine via GLB export. It is designed for developers and digital artists who need controllable, high-quality static fabric for games, archviz, or product rendering without the unpredictability or computational cost of real-time cloth simulation.

Works with✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ammosu/claude-threejs-photoreal/tree/HEAD/skills/threejs-procedural-cloth

Installed? Explore more Image skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

What does Procedural Cloth (No Simulation) do?

Source: room-at-dawn (MIT), src/scene/parts/bed.js for the quilt, blanket, and pillow. This separates it into a reusable library with a stage-by-stage example viewer.

Core idea: Cloth is not "simulated", it's "designed". Define "how much higher each point of the cloth is above its support" on a flat coordinate plane, then wrap that plane onto the support. The benefit is that each step is controllable and reproducible (same seed always gives the same result), builds in under 0.5 seconds, and other objects (books, phones, another blanket) can directly query the same height function, guaranteeing they sit on the fabric's surface. The trade-off is the cloth is static: it won't be pushed by characters (for interactivity, see references/engines.md).

Files

PathContent
scripts/cloth.jsLibrary (ES module, depends only on three): RNG/noise, Field, Lobes, FoldFamily, CreaseSet, support drape, curl, grid, UV flattening, wrinkle textures, prints, cotton material, exportableMesh (pre-GLB conversion)
example/index.html + main.jsAn unmade quilt on a bed, ?stage=1..5 to incrementally add each effect
scripts/curtain.jsCurtain: curtainPanel (cross-section integration without stretch), auditPanel, linenTextures, curtainMaterial (stitching, hem, storage creases, backlight transmission, micro-sway), curtainRing
example/curtain.htmlA pair of curtains hanging in front of a window, ?cam= (front, angle, top, hem, stitch, above), ?tied=1, ?fullness=, ?loops=, ?tex=checker
example/preview-*.jpgFinished and stage-by-stage preview images of the example (preview-curtain.jpg is the curtain)
references/shape.mdHeight field design: lobes, directional folds, peak erosion, creases, flat zones
references/drape-curl.mdSupports, toppling, planar distortion, corner curl, hems, placing objects on cloth, adding a second layer
references/uv-material.mdUV flattening, fine wrinkle normal map + cavity, prints, materials
references/verification.mdWhat data to check, which camera angles to use, common symptom troubleshooting
references/curtain.mdCurtains: cross-section integration and width solving, composition of θ(s), materials, parameters, verification, known issues
references/engines.mdPorting to Godot/Unreal: exporting GLB, rewriting in GDScript/C++, integrating interactive cloth

Running the Example

cd <skill folder> && python3 -m http.server 5420 --bind 127.0.0.1
# Open http://127.0.0.1:5420/example/

(<skill folder> is the Base directory shown when loading this skill; when installed as a plugin it is under ~/.claude/plugins/cache/)

URL parameters:

  • stage=1..5: respectively, lobes, add directional folds, add peak erosion, add creases, add corner curl and toppling.
  • cam=wide|close|top|side|left|foot: camera presets.
  • tex=checker: switch to a 10 cm checkerboard to check UV stretching.
  • relax=0: turn off UV flattening for comparison.
  • ui=0: hide the data panel, useful for screenshots.

When finished, window.__cloth exposes verification data, and body[data-ready="1"] indicates screenshots can be taken. The "Download GLB" button can export the cloth for use in other engines.

Process

StepWhat it doesWhyLibrary functions
1Define the outline (four corners) and "distance to hem" in flat coordinatesUsed for hems, crease fading, corner curlsquadEdge
2Lobes: manually place 5–10 ellipses, each with their own height and angle, combined with smooth-maxThe large shape defines "what state is the quilt in"—noise can't achieve this.makeLobes, lobesAt
3Directional folds: 2–3 sets of billow noise with direction, switching direction per regionFolds in a quilt run along the direction of tension.foldFamily
4Vertical waves on the draping part; overall domain warp; soft cap to limit heightDraping fabric isn't flat; avoid ruler-straight lines; keep the tallest lobe from being excessive.softCap
5Peak erosion: each point is at most ~1.2 cm higher than its surroundings (after blurring twice), valleys stay sharpFilled quilts don't have sharp peaks; this turns it from "mountains" into "a quilt".Field.erodePeaks
6Creases drawn one by one: fan out from pinch points, plus spread elsewhere following the tension field, attenuating near flat zones and hemsCreases made with noise look like marble; use "tent-shaped profile" line segments.CreaseSet, crease
7Hem: flat band, stitch groove, puckeringThe edge is real geometry; it must be convincing up close.example hemElev
8Wrap onto support: flat area + rounded corners + vertical dropA single plane can represent both the on-bed and off-bed parts.boxSupport
9High folds topple to one side: the tipping distance depends on the local heightA bulge becomes steep on one side and gentle on the other, not like a symmetrical dome.example place
10Corner curl: parts beyond the fold line are first rolled up along a cylinder, then laid flat back on the quilt; the flattened area is marked as a flat zoneAdds a storytelling detail.curl
11Flatten UV based on the 3D surface (multi-resolution mesh, edge-length constraints)Prints aren't stretched on steep folds.relaxUV, uvStretch
12Material: tiled fine-wrinkle normal map (alpha stores cavity) + print + sheenGeometry handles centimeter scale; textures handle millimeter scale.wrinkleTexture, sprigPrintTexture, cottonMaterial

Rules to Follow

  1. Random must use RNG(seed) / pn(...,seed), never Math.random(). Screenshot regression, baked lighting, and multi-user sync all rely on it.
  2. Sample large shapes with cubic interpolation (Field.cubic), creases with bilinear (Field.bil). If large shapes use bilinear, 5 mm grid facets become visible on the mesh.
  3. Do not make creases with noise. Noise produces blobs; real creases are directional, tapering lines.
  4. Erode peaks first, then add creases. If the order is reversed, the ridge lines of creases will also be eroded.
  5. The flat zone under the curled corner must cover the entire folded range (the example uses QMAX to compute it automatically). If it's not fully covered, the flipped part will stack on top of high lobes, and the pattern will stretch into stripes (this actually happened; see references/verification.md).
  6. UV flattening uses the "unflipped" shape U; stretching of the flipped part must be checked separately. relaxUV requires the grid count to be a multiple of 8.
  7. Draping cloth must not collide with objects underneath: the example makes the bed frame narrower than the mattress. Collision with anything other than the support is outside this method's scope.
  8. When two adjacent sides both drape, the corner needs a conical or triangular gore; boxSupport does not handle this. Only allow two opposite sides to drape.

Numerical Starting Points (Measured in Example)

  • Quilt flat thickness: 5 cm; lobe height × LOBE_SCALE (0.3 is normally slept on, 1 is piled into big rolls); maximum soft cap 23 cm.
  • Directional fold spacing ~12 cm, length ~60 cm, amplitude 3–4 cm; erosion radius 5 grid cells (2.5 cm), upper limit 1.2 cm.
  • Creases: width 2.4–4 cm, height ~0.16–0.3× width, 30% are grooves; each pinch point 4–7 creases, other areas have ~200 scattered groups.
  • Grid size ~7 mm (288×192), ~130k triangles, modeling time ~0.45 s (UV flattening ~0.15 s), zero interpenetration, UV stretch p5/p95 ~0.92/1.08.

Curtains (Hanging Fabric)

The quilt method is "height field wrapped onto a support"—not suitable for curtains. Curtains use: each horizontal cross-section is a fixed-length line segment, drawn by integrating the travel angle θ(s) along the cloth, then using binary search to adjust the multiplier of θ so that the column exactly equals the required width at that height. The cloth doesn't stretch, so UV is directly in meters, and textures don't deform. See references/curtain.md for details.

import { curtainPanel, auditPanel, linenTextures, curtainMaterial, curtainRing, CU } from './scripts/curtain.js';
const p = curtainPanel({ x0t: 0.27, x1t: 0.95, x0h: 0.25, x1h: 0.97, zc: 0.12, yTop: 2.29, yHem: 0.02, loops: 7, seed: 4101 });
const lin = linenTextures();
scene.add(new THREE.Mesh(p.geo, curtainMaterial({ map: lin.map, normalMap: lin.normalMap, yTop: 2.29 })));
console.log(auditPanel(p));   // crossings must be 0; stretchP95Pct should be < 1
  • Measured in example: one panel ~100k triangles, built in 0.2 s, stretch p95 0.4–0.7 %, zero crossings.
  • Pitfall: if depth is too tight, the cloth loses 5–15 % width. If space is limited, lower fullness; don't compress depth.
  • Pitfall: if the hem is too narrow, folds interpenetrate; the threshold depends on seed (the right panel in the example still had crossings at ~0.67×, only passed at 0.79×). Check crossings; change seed if needed.
  • Default depth [-0.11, 0.16] doesn't shorten the cloth, but the rod must be ~12 cm from the wall.

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

threejs-photoreal-interior

用 three.js 從零做一個照片級的室內場景,完全用程式生成、不需要模型檔、貼圖或 HDRI 的總綱與起手式。內容包括:整體流程(尺寸與座標 → 外殼與窗 → 主角物件 → 材質 → 小物 → 烘焙光照 → 後製 → 驗證 → 電影輸出)、各步驟該用哪個 skill、跨 skill 整合的規則(決定性、細分、材質要經過 GI 補丁且保留原本的 shader 補丁、反照率、太陽直射與烘焙分工、陰影漏光)、一個指令就能建立可執行的新專案(房間、窗、木地板、牆面、桌椅、掛在椅背的毛巾、書架、杯子、水壺、現場烘焙、後製),以及驗收清單和實測數字。當使用者說「做一個寫實的房間/室內」「three.js 照片級場景」「程式生成整個場景」「不用模型做室內」「room-at-dawn 那種」「從哪裡開始做寫實 3D 場景」「開一個新的寫實場景專案」「把這些 skill 串起來」「寫實室內場景流程」時使用;做其中單一環節時,直接用對應的子 skill。

threejs-procedural-textures

在 three.js 用程式即時生成照片級材質貼圖(不用任何圖檔):可無縫重複的雜訊、以公釐為單位的高度場轉 normal map、粗糙度與 AO 打包、Canvas2D 轉貼圖、平均反照率(給光照烘焙用)、接縫檢查。內含現成的材質:滾筒漆木屑壁紙加上大尺度的灰泥與漆色變化、烤漆橘皮紋、手摸過的粗糙度、積灰、橡木地板(交錯接縫、每片紋理不同、節疤、四邊微倒角)、通用木紋、對拼橡木貼皮、平織、鬆餅格、毛巾布、羅紋、針織、毛氈、棉繩、使用痕跡(灰塵、油脂、指紋、碎屑、棉絮、頭髮、杯印、細刮痕,同時畫進顏色與粗糙度)、斑點釉、粉體塗裝刮傷、書封圖集與對應 UV 的書本幾何、書頁邊、地形圖海報、照片、假文字。當使用者說「程式生成貼圖」「procedural texture」「不用圖檔的材質」「normal map 怎麼產生」「木地板/木紋貼圖」「牆面看起來太假」「布料材質」「針織/毛巾布 normal map」「使用痕跡」「刮痕/指紋/灰塵」「粗糙度貼圖」「書封/書背」「假文字」「貼圖有接縫」「Canvas 畫貼圖」時使用。

threejs-sky-backdrop

在 three.js 用程式做天空與窗外遠景,不需要 HDRI 或圖檔。天空的同一份參數同時用在三個地方:烘焙光照用的解析式天空、看得到的天空球(雲層、高空薄雲、地平線霧帶、太陽),以及不烘焙時用的太陽光、半球光與環境貼圖。內含四種預設(清晨、白天、陰天、黃昏)和一個量測工具,確認看到的天空和照亮場景的天空亮度一致。遠景部分包括:只建從室內窗戶看得到的東西(窗洞可見性與 LOD)、隨距離變淡的大氣霧化、遠處逐漸變粗的草地網格、碎石小路、樹籬、鄰居房子(陶瓦屋頂、窗戶、煙囪、天窗)、封住地平線的遠方樹牆,並可以搭配 threejs-procedural-vegetation 種樹。當使用者說「天空」「sky shader」「雲」「程式生成天空」「不用 HDRI」「窗外景色」「遠景」「背景房子」「地平線」「大氣透視」「霧化」「窗外的樹」「天空和光照對不上」「清晨/黃昏/陰天的天空」「只建看得到的東西」時使用。

Related Skills