Build "Whole Orange Jelly" — a single self-contained HTML file (inline JS/CSS, no libraries): a real-time WebGPU soft-body whole orange made of jelly. The user can grab and stretch it, and cut it with a knife into wheels, wedges and small pieces. Every piece is its own wobbling body.
Shape and pieces
- The orange is a signed distance field: a gently oblate ellipsoid (polar half-length 1.27 along x, equatorial radius 1.36) lying on its side, with a softly flattened seat on the floor.
- Every piece is that field clipped by the half-spaces n·X ≤ c of the cuts that made it, with the fresh edges rounded (smooth max, k ≈ 0.085). All pieces share the orange's original rest frame, so the anatomy stays where it grew.
- Per piece:
- a surface-nets render skin (0.042 grid) projected onto the field;
- a hex lattice for the simulation in the piece's own principal frame, with boundary nodes snapped to the surface;
- barycentric embedding of render vertices into the lattice tets.
- Up to 30 pieces; slivers are rejected.
Anatomy (all in rest space, so every cut shows it where it really is)
- Zest (0.07 deep) with oil-gland pores, a mottled tone, a green stem button at one end and a small navel at the other.
- White pith (to 0.19 deep).
- 11 segments around the stem axis, with thin milky membrane walls (slightly jittered, bowed and wandering along the axis) and a pithy core along the axis.
- Juice vesicles: teardrop sacs fanning out from the core within each segment.
- 16 pale citrus pips near the core, pointed end inward; a few small bubbles in the flesh.
- A pip that a cut goes through is kept by the side holding its centre and eased just under the new face.
Physics (XPBD)
- Per piece: hex cells with co-rotational shape matching plus volume constraints on their five tets.
- Zest and pith firmer than the flesh.
- Edge and deformation damping; floor contact with Coulomb friction and a little rolling resistance.
- Piece–piece contact against each other's exact rest shape in a best-fit frame.
- Sleeping pieces that wake on touch; fixed 60 Hz step with small substeps.
Knife
- A nakiri-style knife: draw a stroke across the orange.
- The stroke, read on the top of what it crosses, fixes a vertical blade plane, carried into each crossed piece's rest frame by its best-fit rotation and added as a half-space.
- The new pieces are built incrementally while the knife lines up, presses a groove and cuts straight down. They take over the position and speed of the jelly they came from, and the blade wedges the faces apart.
Rendering (WebGPU / WGSL)
- Procedural photo studio. Soft PCSS key shadow tinted by the jelly, plus contact AO from a height map.
- Back-face thickness; refraction of the scene, with each tap dimmed by its own path length.
- A volumetric march through the jelly in rest space, using a per-vertex inverse deformation gradient:
- zest, pith, membranes/core and flesh each absorb with their own colour (Beer–Lambert);
- scattering is grey (only absorption is coloured), so light scattered out of orange flesh stays orange.
- The white pith, the membrane star and the core read crisply on cut faces.
- Back-lit glow at thin edges, Fresnel studio reflections, GGX highlights, sugar-crystal glints.
- Post: Khronos PBR Neutral tone mapping, sRGB, dither.
UI (editorial "Material Studies / No. 032", English)
- Italic serif title "Whole / Orange." with the caption "Eleven segments, set in jelly. Zest, pith and juice. Cut it as small as you like."
- Status pill "WEBGPU · LIVE".
- Tools: Hand / Knife. Varieties: Navel, Blood, Cara Cara.
- Firmness and Internal damping sliders; Give it a nudge, Reset, Pause; ¼ speed and Show mesh.
- Readouts: Mass (g, 1 unit ≈ 3 cm at 1.3 g/cm³), Volume (% of rest), Kinetic (mJ), Pieces.
- A collapsible "Inside the experiment" with notes on the method.
- Fallback without WebGPU. Stacked mobile layout with no horizontal scroll.
한국어 번역
"Whole Orange Jelly"를 만들어라 — 하나의 자체 완결형 HTML 파일(인라인 JS/CSS, 라이브러리 없음): 젤리로 만든 실시간 WebGPU 소프트 바디 통오렌지. 사용자가 잡아당겨 늘릴 수 있고, 칼로 잘라 슬라이스, 웨지, 작은 조각들로 나눌 수 있다. 모든 조각은 각자 흔들거리는 개별 바디다.
형태와 조각
- 오렌지는 부호 있는 거리장이다: 옆으로 누운 완만한 편평 타원체(x축 방향 극 반지름 1.27, 적도 반지름 1.36)이며, 바닥에 닿는 부분은 부드럽게 눌린 받침이 있다.
- 각 조각은 그 장을, 조각을 만들어낸 절단면들의 반공간 n·X ≤ c로 잘라낸 것이고, 새로 생긴 가장자리는 둥글게 처리한다(스무스 맥스, k ≈ 0.085). 모든 조각은 오렌지의 원래 정지 좌표계를 공유하므로 해부 구조는 자라난 자리에 그대로 남는다.
- 조각마다:
- 장 위로 투영된 서피스 넷 렌더 스킨(0.042 격자);
- 조각 자신의 주축 프레임에서 시뮬레이션하기 위한 육각 격자, 경계 노드는 표면에 스냅된다;
- 렌더 정점들을 격자 사면체들에 무게중심 좌표로 임베딩.
- 최대 30개 조각; 가느다란 조각은 거부된다.
해부 구조 (모두 정지 공간 기준이므로, 어떤 절단이든 실제 있는 자리에 그대로 드러난다)
- 유분샘 구멍과 얼룩진 색조가 있는 겉껍질(깊이 0.07), 한쪽 끝에는 초록색 꼭지 버튼, 다른 쪽 끝에는 작은 배꼽.
- 흰 속껍질(깊이 0.19까지).
- 꼭지 축 둘레의 11개 세그먼트, 얇고 유백색인 막 벽(약간 흔들리고, 휘어지고, 축을 따라 구불거린다)과 축을 따라 이어지는 속껍질 심.
- 과즙 소포: 각 세그먼트 안에서 심으로부터 부챗살처럼 뻗어 나오는 물방울 모양 주머니.
- 심 근처의 창백한 감귤 씨 16개, 뾰족한 끝은 안쪽을 향한다; 과육 속에는 작은 기포 몇 개.
- 절단면이 지나간 씨는 그 중심을 품은 쪽이 유지하며, 새 절단면 바로 아래로 살짝 밀어 넣는다.
물리 (XPBD)
- 조각마다: 공회전 형상 매칭이 적용된 육각 셀과, 그 다섯 사면체에 대한 부피 제약.
- 겉껍질과 흰 속껍질은 과육보다 단단하다.
- 모서리 및 변형 감쇠; 쿨롱 마찰과 약간의 구름 저항이 있는 바닥 접촉.
- 최적 적합 프레임에서 서로의 정확한 정지 형상에 대한 조각 간 접촉.
- 접촉하면 깨어나는 슬리핑 조각; 작은 서브스텝을 사용하는 고정 60 Hz 스텝.
칼
- 나키리 스타일 칼: 오렌지를 가로질러 한 획을 긋는다.
- 그 획은 교차하는 대상의 상단에서 읽혀 수직 칼날 평면을 정하고, 교차된 각 조각의 정지 프레임으로 최적 적합 회전을 통해 옮겨져 반공간으로 추가된다.
- 새 조각은 칼이 정렬하고, 홈을 누르고, 곧장 아래로 절단하는 동안 점진적으로 만들어진다. 이들은 원래 젤리의 위치와 속도를 이어받고, 칼날은 절단면을 벌려 놓는다.
렌더링 (WebGPU / WGSL)
- 절차적 포토 스튜디오. 젤리에 의해 색이 입혀지는 부드러운 PCSS 키 섀도, 그리고 높이 맵에서 나온 접촉 AO.
- 뒷면 두께; 장면의 굴절, 각 탭은 자기 경로 길이만큼 어두워진다.
- 정지 공간에서 젤리를 통과하는 볼류메트릭 마치, 정점별 역변형 그래디언트 사용:
- 겉껍질, 흰 속껍질, 막/심, 과육은 각자 자신의 색으로 흡수한다(Beer–Lambert);
- 산란은 회색이다(흡수만 색을 띤다), 그래서 오렌지 과육에서 산란되어 나오는 빛은 주황색으로 남는다.
- 흰 속껍질, 별 모양 막, 심은 절단면에서 선명하게 읽힌다.
- 얇은 가장자리의 역광 발광, 프레넬 스튜디오 반사, GGX 하이라이트, 설탕 결정의 반짝임.
- 후처리: Khronos PBR Neutral 톤 매핑, sRGB, 디더.
UI (에디토리얼 "Material Studies / No. 032", 영어)
- 이탤릭 세리프 제목 "Whole / Orange."와 캡션 "Eleven segments, set in jelly. Zest, pith and juice. Cut it as small as you like."
- 상태 필 "WEBGPU · LIVE".
- 도구: Hand / Knife. 품종: Navel, Blood, Cara Cara.
- Firmness 및 Internal damping 슬라이더; Give it a nudge, Reset, Pause; ¼ 속도 및 Show mesh.
- 표시값: Mass(g, 1 단위 ≈ 3 cm, 1.3 g/cm³ 기준), Volume(정지 상태 대비 %), Kinetic(mJ), Pieces.
- 방법에 대한 노트가 담긴 접이식 "Inside the experiment".
- WebGPU가 없을 때의 폴백. 가로 스크롤이 없는 스택형 모바일 레이아웃.