Programmatischer Stoff (ohne Simulation)
Quelle: room-at-dawn (MIT), src/scene/parts/bed.js (Bettdecke, Decke, Kissen).
Hier wird es in eine wiederverwendbare Bibliothek zerlegt, mit einem schrittweise anzeigbaren Beispiel.
Kernidee: Der Stoff wird nicht „simuliert“, sondern „designt“.
Auf einer ebenen Fläche wird definiert, „wie viel höher jeder Punkt des Stoffs über dem Träger ist“, und dann wird diese Ebene auf das Trägerobjekt projiziert.
Vorteil: Jeder Schritt ist kontrollierbar und reproduzierbar (derselbe Seed liefert immer dasselbe), Aufbau in unter 0,5 Sekunden,
und andere Objekte (Buch, Handy, eine weitere Decke) können dieselbe Höhenfunktion abfragen und liegen dadurch garantiert auf der Stoffoberfläche.
Nachteil: Der Stoff ist statisch – er wird nicht durch Figuren bewegt (für Interaktion siehe references/engines.md).
Dateien
| Pfad | Inhalt |
|---|---|
scripts/cloth.js | Bibliothek (ES-Modul, nur three.js als Abhängigkeit): RNG/Rauschen, Feld, Klumpen, Faltenfamilien, Falten, Drapierung auf Träger, Umschlagen von Ecken, Gitter, UV-Glättung, Falten-Textur, Muster, Baumwoll-Material, exportableMesh (Umwandlung vor GLB-Export) |
example/index.html + main.js | Ein ungemachtes Bett mit Decke, ?stage=1..5 fügt schrittweise Effekte hinzu |
scripts/curtain.js | Vorhänge: curtainPanel (Querschnittsintegration ohne Dehnung), auditPanel, linenTextures (Leinwandbindung), curtainMaterial (Säume, Nähte, Raffungen, Lichtdurchlässigkeit, leichte Bewegung), curtainRing |
example/curtain.html | Ein Paar Vorhänge vor einem Fenster, ?cam= (front, angle, top, hem, stitch, above), ?tied=1, ?fullness=, ?loops=, ?tex=checker |
example/preview-*.jpg | Fertigbilder und Zwischenschritte des Beispiels (preview-curtain.jpg ist der Vorhang) |
references/shape.md | Höhenfeld-Design: Klumpen, lange Falten, Spitzenabflachung, Falten, glatte Bereiche |
references/drape-curl.md | Träger, Umfallen, Planare Verzerrung, Ecken umschlagen, Säume, Gegenstände auf dem Stoff, zweite Stoffschicht |
references/uv-material.md | UV-Glättung, feine Falten-Normal-Map + Vertiefungs-Abdunklung, Muster, Material |
references/verification.md | Welche Daten, welche Kameraperspektiven, häufige Symptome und deren Behebung |
references/curtain.md | Vorhänge: Querschnittsintegration und Breitenlösung, Zusammensetzung von θ(s), Material, Parameter, Verifikation, bekannte Probleme |
references/engines.md | Portierung nach Godot/Unreal: GLB-Export, Umschreiben in GDScript/C++, Integration von interaktivem Stoff |
Beispiel ausführen
cd <Skill-Ordner> && python3 -m http.server 5420 --bind 127.0.0.1
# Öffne http://127.0.0.1:5420/example/
(<Skill-Ordner> ist das bei Laden des Skills angezeigte Basisverzeichnis; als Plugin liegt es unter ~/.claude/plugins/cache/)
URL-Parameter:
stage=1..5: Zeigt schrittweise Klumpen, lange Falten, Spitzenabflachung, Falten, umgeschlagene Ecken und Umfallen.cam=wide|close|top|side|left|foot: Voreingestellte Kameraperspektive.tex=checker: Wechselt zu einem 10-cm-Schachbrettmuster, um UV-Verzerrung zu prüfen.relax=0: Schaltet UV-Glättung aus, zum Vergleich.ui=0: Blendet das Datenpanel aus (für Screenshots).
Nach Abschluss enthält window.__cloth die Verifikationsdaten, body[data-ready="1"] signalisiert Bereitschaft für Screenshots.
Der Button „GLB herunterladen“ exportiert den Stoff für andere Engines.
Ablauf
| Schritt | Was | Warum | Bibliothek |
|---|---|---|---|
| 1 | Kontur (Viereck) und „Abstand zum Saum“ in der Ebene definieren | Für Säume, Ausblenden von Falten, umgeschlagene Ecken | quadEdge |
| 2 | Klumpen: 5–10 manuell platzierte Ellipsen mit eigener Höhe und Ausrichtung, per Smooth-Max verbunden | Großform bestimmt „in welchem Zustand ist die Decke“; Rauschen allein reicht nicht | makeLobes lobesAt |
| 3 | Lange Falten: 2–3 Gruppen gerichteter Billow-Rauschfelder, je nach Bereich mit wechselnder Richtung | Die Falten einer Decke verlaufen entlang der Zugrichtung | foldFamily |
| 4 | Längliche Wellen für hängende Bereiche; globales Domain Warp; Soft Cap zur Höhenbegrenzung | Hängender Stoff ist nicht flach; vermeidet Lineal-artige Kanten; höchster Klumpen nicht übertrieben | softCap |
| 5 | Spitzenabflachung: Jeder Punkt ist maximal etwa 1,2 cm höher als die Umgebung (nach zweimaligem Weichzeichnen), Täler bleiben scharf | Stoff mit Füllung hat keine spitzen Gipfel; macht aus einem „Berg“ eine „Decke“ | Field.erodePeaks |
| 6 | Falten einzeln zeichnen: Vom Greifpunkt fächerförmig ausstrahlend, plus weitere verteilt entlang des Spannungsfelds, in glatten Bereichen und nahe Säumen abgeschwächt | Falten mit Rauschen sehen aus wie Marmor; benötigt „Zeltprofil“-Liniensegmente | CreaseSet crease |
| 7 | Saum: flaches Band, Nahtrille, Kräuselung | Der Rand ist echte Geometrie, muss aus der Nähe glaubwürdig sein | Beispiel hemElev |
| 8 | Auf Träger projizieren: flacher Bereich + runde Kante + senkrecht nach unten | Eine einzige Ebene kann gleichzeitig Bett und Bettkante darstellen | boxSupport |
| 9 | Hohe Falten zur Seite legen: Der Versatz hängt von der Höhe an dieser Stelle ab | Beulen werden einseitig steil, einseitig flach, nicht wie symmetrische Brötchen | Beispiel place |
| 10 | Ecken umschlagen: Der Teil jenseits der Bruchlinie wird zuerst um einen Zylinder gerollt, dann flach auf die Decke gelegt; der überlappte Bereich wird als glatt markiert | Fügt ein erzählerisches Detail hinzu | curl |
| 11 | UV-Glättung über die 3D-Oberfläche (Mehrgitterverfahren, Kantenlängen-Constraints) | Muster werden auf steilen Falten nicht in die Länge gezogen | relaxUV uvStretch |
| 12 | Material: Wiederholbare feine Falten-Normal-Map (Alpha = Vertiefungen) + Muster + Sheen | Geometrie regelt Zentimeter, Textur regelt Millimeter | wrinkleTexture sprigPrintTexture cottonMaterial |
Wichtige Regeln
- Zufall immer über
RNG(seed)/pn(...,seed), niemalsMath.random(). Screenshot-Regressionen, Backen von Beleuchtung, Multi-User-Synchronisation hängen davon ab. - Großformen mit kubischer Interpolation (
Field.cubic) abtasten, Falten mit bilinearer (Field.bil). Bei bilinearer Interpolation von Großformen sind auf dem Gitter 5-mm-Kästchen sichtbar. - Falten nicht mit Rauschen erzeugen. Rauschen ergibt Klumpen; echte Falten sind gerichtet und laufen an beiden Enden spitz zu.
- Erst Spitzen abflachen, dann Falten hinzufügen. Bei umgekehrter Reihenfolge werden die Faltenrücken ebenfalls abgeflacht.
- Der glatte Bereich unter der umgeschlagenen Ecke muss den gesamten Umschlagbereich abdecken (Beispiel verwendet
QMAXzur automatischen Berechnung). Sonst liegt die umgeschlagene Kante auf hohen Klumpen und das Muster wird linear verzerrt (ist passiert, siehereferences/verification.md). - UV-Glättung verwendet die „nicht umgeschlagene“ Form U; die Verzerrung des umgeschlagenen Teils muss separat geprüft werden.
relaxUVerwartet Gitterauflösung als Vielfaches von 8. - Hängender Stoff darf nicht mit darunter liegenden Objekten kollidieren: Im Beispiel ist der Bettrahmen schmaler als die Matratze. Kollisionen außerhalb des Trägers werden von dieser Methode nicht behandelt.
- Wenn zwei benachbarte Kanten gleichzeitig herunterhängen, wird an der Ecke ein konischer Stoff- oder Dreieckslappen benötigt;
boxSupportbehandelt dies nicht. Bitte nur gegenüberliegende Kanten herunterhängen lassen.
Startwerte (im Beispiel getestet)
- Dicke der flachen Decke 5 cm, Klumpenhöhe ×
LOBE_SCALE(0.3 = normal benutzt, 1 = zu großen Wulst gestapelt), maximale Soft-Cap 23 cm. - Abstand langer Falten ca. 12 cm, Länge ca. 60 cm, Amplitude 3–4 cm; Abflachungsradius 5 Gittereinheiten (2,5 cm), Obergrenze 1,2 cm.
- Faltenbreite 2,4–4 cm, Höhe ca. 0,16–0,3 der Breite, 30 % sind Rillen; 4–7 Falten pro Greifpunkt, 200 Gruppen verteilt.
- Gitter ca. 7 mm (288×192), ca. 130.000 Dreiecke, Aufbau ca. 0,45 s (davon UV-Glättung ca. 0,15 s), Überlappungen 0, UV-Verzerrung p5/p95 ca. 0,92/1,08.
Vorhänge (hängender Stoff)
Die Methode für Bettdecken („Höhenfeld auf Träger projizieren“) ist für Vorhänge nicht geeignet. Vorhänge verwenden stattdessen: Jeder horizontale Querschnitt ist ein Seil mit fester Länge, das entlang des fortschreitenden Winkels θ(s) gezeichnet wird. Mit einem Bisektionsverfahren wird der Faktor von θ so angepasst, dass diese Reihe genau der gewünschten Breite auf dieser Höhe entspricht. Der Stoff dehnt sich nicht, daher wird UV direkt in Metern gemessen und die Textur verzerrt sich nicht. Details in references/curtain.md.
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 muss 0 sein; stretchP95Pct sollte < 1 sein
- Im Beispiel getestet: Ein Panel ca. 100.000 Dreiecke, Aufbau 0,2 s, Verzerrung p95 0,4–0,7 %, Überkreuzungen 0.
- Fallstrick: Wenn
depthzu eng eingestellt ist, fehlen 5–15 % des Stoffvolumens. Bei Platzmangelfullnessreduzieren, nicht die Tiefe. - Fallstrick: Wenn der Saum zu schmal wird, kreuzen sich die Falten gegenseitig – der Schwellwert hängt vom Seed ab (im Beispiel hat das rechte Panel noch bei ca. 0,67-fach Überkreuzungen, erst bei 0,79-fach ist es frei).
crossingsprüfen, ggf. Seed wechseln. - Standard
depth[-0.11, 0.16] verkürzt den Stoff nicht, die Stange sollte ca. 12 cm von der Wand entfernt sein.