Build "Citrus Jelly" — a single self-contained HTML file (inline JS/CSS, no libraries) with a real-time WebGPU soft-body jelly shaped like a half-moon citrus slice that the user can grab, stretch and let go.
Object
- A rounded half-moon slice: half-disk profile extruded into a thick slab with softly rounded edges; flat cut edge on the bottom, arc on top.
- Three material zones by radius: translucent fruit flesh inside, a pale pith band, and a thin glossy rind along the arc (the cut edge is all flesh).
- Inside the jelly: thin milky radial membranes between the segments (inset from both faces), a few seeds, small air bubbles with a faint rim and a pin-point highlight, and tiny sub-surface glints like sugar crystals.
Physics (XPBD tetrahedral soft body)
- Mesh: 2D Bowyer–Watson Delaunay of the profile, extruded into prisms and split into tets. Render mesh embedded in sim tets with barycentric coordinates.
- Constraints:
- co-rotational per-tet shape matching (warm-started quaternion, Müller 2016), which recovers inverted tets;
- tet volume constraints for near-incompressibility;
- hard edge strain limits (max 1.8×, min 0.35× rest length).
- Fixed timestep, "small steps" XPBD (many substeps, 1 iteration each).
- Damping: relative-velocity damping along edges, light air drag, and settling that bleeds off residual jitter.
- Floor contact with Coulomb-style positional friction (static and kinetic). Never crush the held patch into the floor; lift the patch instead.
- Grab and pull:
- pick a surface point with the mouse or touch;
- the patch around it is attached softly;
- reach is bounded, so stretching is strong but never unbounded;
- on release the slice wobbles back.
- Safety: reset gently if any value becomes NaN.
Rendering (WebGPU / WGSL)
- Procedural photo studio: pale cyclorama paper sweep, overhead softbox, back-left strip light, front-right fill card.
- Jelly material:
- refraction of the scene through the slice;
- view-ray thickness from a back-face depth pass, used for Beer–Lambert absorption;
- Fresnel studio reflections and a key highlight.
- Soft PCSS-style floor shadows, tinted by the jelly color.
- Post: exposure, Khronos PBR Neutral tone mapping, sRGB, dither. Optional mesh-overlay debug view.
UI (minimal editorial style, English)
- Corner label "Material Studies / No. 010", big title "Citrus / Jelly.", hint "Grab. Stretch. Let go."
- Variety swatches: Orange, Blood Orange, Lemon. Each changes the flesh, pith and rind colors.
- Sliders: Firmness (log-mapped edge compliance) and Internal damping.
- Buttons:
- "Give it a nudge": a small hop with a twist;
- Reset;
- Pause.
- Keys: Space to pause, N to nudge, R to reset.
- Fallback screen "This slice needs WebGPU." when the browser has no WebGPU.
- Responsive: works on mobile with touch and no horizontal scroll.
한국어 번역
"Citrus Jelly"를 만들어 주세요 — 단일 자체 포함 HTML 파일(인라인 JS/CSS, 라이브러리 없음)로, 사용자가 잡고 늘렸다 놓을 수 있는 반달 모양의 감귤 조각 형태 실시간 WebGPU 소프트 바디 젤리입니다.
오브젝트
- 둥근 반달 조각: 반원 프로파일을 부드럽게 둥근 가장자리의 두꺼운 슬래브로 압출; 아래는 평평한 절단면, 위는 호.
- 반지름 방향으로 세 가지 머티리얼 영역: 내부의 반투명 과육, 창백한 흰 껍질(pith) 띠, 그리고 호를 따라 얇고 광택 있는 과피(절단면은 전부 과육).
- 젤리 내부: 세그먼트 사이의 얇고 유백색인 방사형 막(양면에서 인셋), 몇 개의 씨앗, 희미한 테두리와 점 같은 하이라이트가 있는 작은 기포, 설탕 결정 같은 미세한 서브서피스 반짝임.
물리 (XPBD 사면체 소프트 바디)
- 메시: 프로파일의 2D Bowyer–Watson 들로네 삼각분할을 프리즘으로 압출하고 사면체로 분할. 렌더 메시는 무게중심 좌표로 시뮬레이션 사면체에 임베드.
- 제약:
- 사면체별 공회전 형상 매칭(웜 스타트 쿼터니언, Müller 2016)으로 뒤집힌 사면체를 복원;
- 거의 비압축성을 위한 사면체 부피 제약;
- 하드 에지 변형률 한계(최대 1.8×, 최소 0.35× 휴지 길이).
- 고정 타임스텝, "small steps" XPBD(많은 서브스텝, 각 1회 반복).
- 감쇠: 에지를 따른 상대 속도 감쇠, 가벼운 공기 저항, 잔여 지터를 빼내는 정착.
- 쿨롱식 위치 기반 마찰(정지 및 운동)을 적용한 바닥 접촉. 잡고 있는 패치를 바닥으로 절대 짓누르지 말고, 패치를 들어 올릴 것.
- 잡기와 당기기:
- 마우스나 터치로 표면 점을 선택;
- 그 주변 패치가 부드럽게 부착;
- 도달 범위가 제한되어 늘어남은 강하지만 무한하지는 않음;
- 놓으면 조각이 흔들리며 돌아옴.
- 안전: 어떤 값이든 NaN이 되면 부드럽게 리셋.
렌더링 (WebGPU / WGSL)
- 절차적 포토 스튜디오: 창백한 사이클로라마 종이 스윕, 오버헤드 소프트박스, 왼쪽 뒤 스트립 라이트, 오른쪽 앞 필 카드.
- 젤리 머티리얼:
- 조각을 통한 장면의 굴절;
- 백페이스 깊이 패스에서 얻은 시선 광선 두께를 Beer–Lambert 흡수에 사용;
- 프레넬 스튜디오 반사와 키 하이라이트.
- 젤리 색으로 틴트된 부드러운 PCSS 스타일 바닥 그림자.
- 포스트: 노출, Khronos PBR Neutral 톤 매핑, sRGB, 디더. 선택적 메시 오버레이 디버그 뷰.
UI (미니멀 에디토리얼 스타일, 영어)
- 코너 라벨 "Material Studies / No. 010", 큰 제목 "Citrus / Jelly.", 힌트 "Grab. Stretch. Let go."
- 종류 스와치: Orange, Blood Orange, Lemon. 각각 과육, 흰 껍질, 과피 색을 변경.
- 슬라이더: Firmness(로그 매핑된 에지 컴플라이언스) 및 Internal damping.
- 버튼:
- "Give it a nudge": 비틀며 작게 폴짝;
- Reset;
- Pause.
- 키: Space로 일시정지, N으로 넛지, R로 리셋.
- 브라우저에 WebGPU가 없을 때 폴백 화면 "This slice needs WebGPU."
- 반응형: 터치가 되는 모바일에서 가로 스크롤 없이 작동.