먹물 한 방울
한지 위로 떨어진 먹이 터지고 말리며 번진다 — 손으로 저으면 물이 따라 돈다.
설정값 미리보기
바꾼 문구·색으로 다시 재생합니다
프롬프트 설정
Claude 가 읽는 제작 지시문입니다. 직접 읽지 않아도 됩니다.
물에 먹물이 세차게 번지는 유체 시뮬레이션을 HTML 파일 하나로 만들어 줘. 미리보기에서 바로 돌아가게. 길게 설명할 테니 숫자는 그대로 지켜 줘.
목표는 「조용한 명상」이 아니라 먹이 터지듯 피어나 버섯처럼 말리고 줄기로 뻗어 화면을 휘감는 힘 있는 장면이다. 진짜 먹처럼 보여야 하고, 대칭 무늬·별 모양·노이즈 질감처럼 「컴퓨터가 만든 티」가 나면 실패다. 첫 화면부터 먹이 이미 화면을 휘감고 있어야 한다.
[바꿀 곳]
- 색: 한지 #EDE5D5 · 먹 #101218 · 두 번째 먹(주홍) #B8321F
- 먹 떨어지는 간격: 1.6초
- 화면비: 16:9
[크기]
- 모든 길이는 화면 짧은 변(16:9 에서는 높이)에 대한 비율이다. 「픽셀」 단위는 짧은 변 1080px 기준으로 환산해서, 창 크기와 상관없이 움직임이 같게 한다.
- 격자 해상도: 속도장 짧은 변 160, 먹(염료) 짧은 변 1024(휴대폰 512).
- 방울 하나: 중심 먹은 반지름 0.028~0.04 덩어리 셋, 터지는 힘 반경 0.08, 위성 방울은 중심에서 0.06~0.12 떨어진 곳까지. 아래 [먹 한 방울]의 숫자와 같다.
- 배경 흐름: 반지름 0.42 짜리 크고 느린 소용돌이 두 개가 화면을 휘감는다.
[시뮬레이션 — WebGL 셰이더, 이 숫자로]
- 격자 stable fluids, 해상도는 [크기]대로. 먹 텍스처는 두 채널(먹, 주홍).
- 고정 시간 간격 dt = 1/60초로 매 프레임 한 번.
- 압력 투영은 이 식 그대로: 압력에 감쇠 0.8 을 곱한 뒤, 발산 = 0.5·(R − L + T − B), 야코비 p = (L + R + T + B − 발산)/4 를 25회, 기울기 빼기 v −= (R − L, T − B). 기울기에 0.5 를 곱하지 않는다 — 25회로는 큰 흐름의 발산이 덜 지워져서 일부러 두 배로 뺀다. (R·L·T·B 는 오른쪽·왼쪽·위·아래 이웃 칸 값)
- 와도 강화(vorticity confinement) 세기 10. (24 이상이면 격자 눈금 크기의 고른 컬이 화면에 깔려 콜리플라워 같은 노이즈가 된다.)
- 속도 소산 0.25/초.
- 먹 소산: 진한 먹은 0.05/초, 옅은 먹에는 0.22 × (1 − smoothstep(0.05, 0.35, 먹 양))/초를 더한다. 옅은 베일은 빨리 걷히고 짙은 줄기만 오래 남아 대비가 유지된다.
- 화면 가장자리 4% 띠 안에서는 먹 소산을 0.5/초 더한다(먹이 벽에 붙어 액자처럼 짙은 띠가 생기지 않게).
- 배경 흐름: 크고 느린 소용돌이 두 개(서로 반대 방향, 반지름 0.42 짧은 변, 중심은 시간에 따라 천천히 이동)를 매 프레임 힘 70 픽셀/초²로 더해 먹이 멈추지 않고 흐르게 한다.
[먹 한 방울 — 착지 순간 이것들을 더한다]
- 떨어지기 0.35초 전: 그 자리에 그림자 점(지름 0.04 짧은 변, 불투명도 0→35%)이 생겨 줄어들며 착지를 예고한다.
- ① 중심 먹: 가우시안 덩어리 셋. 각 덩어리는 중심에서 0~0.012 짧은 변 무작위 방향으로 어긋나고, 반지름 0.028~0.04 무작위, 먹 양은 합이 2.2 가 되게 무작위로 나눈다(각 몫의 비 0.5~1). 착지 순간부터 완벽한 원이 아니라 울퉁불퉁한 덩어리다.
- ② 터지는 힘: 완전한 원대칭 방사형, 세기 260 픽셀/초, 반경 0.08 짧은 변, 0.22초 동안 (1 − t/0.22)^1.3 로 줄어든다. 이 힘은 압력 투영 뒤, 이류 직전에 더한다(투영 앞에 넣으면 지워진다).
★ 방사형 힘에 sin(n·θ) 같은 각도 변조(꽃잎·lobe·wobble)를 절대 곱하지 않는다. 압력 투영이 원대칭 성분은 지우고 각도 변조 성분만 남겨서 먹이 n갈래 별(X 자)이 된다.
- ③ 모양의 불규칙함은 가장자리 소용돌이로 만든다: 착지 순간 속도장에 작은 가우시안 소용돌이 10~16개를 더한다. 각 소용돌이의 각도는 0~2π 완전 무작위(균등 배치 금지), 중심 거리 = 0.08 × (0.5~1.8) 무작위, 반지름 0.012~0.03(짧은 변) 무작위, 세기 500~1000 픽셀/초 무작위, 부호(시계/반시계)도 각각 무작위. 속도 프로필은 √2·x·exp(0.5 − x²), x = 거리/반지름.
- ④ 방울 전체 회전: 60 픽셀/초로 약하게, 방울마다 방향 무작위, 프로필 (1 − exp(−x²))/x/0.638 (Lamb–Oseen). 150 이상이면 갈고리가 전부 한쪽으로 말려 바람개비 모양이 된다.
- ⑤ 위성 방울: 중심에서 0.06~0.12 짧은 변 떨어진 곳에 작은 먹 5~8개. 각도 무작위, 반지름 0.006~0.014 무작위, 양 0.3~0.9 무작위(크기가 다 같으면 찍은 점처럼 보인다).
[희석 — 먹이 불어나지 않게]
- 먹을 이류할 때 그 자리 속도장의 발산만큼 묽힌다: 먹 *= exp(−0.4 · dt · div). div 는 속도 텍스처를 ±2.5칸 떨어진 곳에서 읽은 중앙차분(촘촘하게 읽으면 격자 점무늬가 생긴다), 단위 1/초, ±10 으로 자른다.
- 퍼지는 곳은 묽어지고 모이는 테두리는 진해진다. 마른 먹 테두리가 저절로 생긴다. (이게 없으면 퍼지는 흐름에서 먹 양이 20배로 불어나 화면이 새까맣게 덮인다.)
[그리기 — 종이에 스민 먹처럼]
- 흡수색 = −ln(먹색 / 종이색) 을 채널별로 구해 가장 큰 채널이 1이 되게 정규화한다. 결과 = 종이 × exp(−k · 흡수색 · 양). 먹 k = 2.4, 주홍 k = 2.0(주홍도 같은 방식으로 흡수색을 구한다). 둘 다 있으면 순서대로 곱한다. k × 양 ≈ 2.7 일 때 정확히 먹색이 나온다. 덧셈 블렌딩·발광 금지.
- 착지 순간은 완전 검정(k·양 ≈ 5), 퍼지며 짙은 남흑, 옅은 베일은 회청 — 세 단계가 보여야 한다.
- 테두리: 먹 양이 주변 평균(5×5 블러)보다 큰 가장자리를 최대 1.6배 진하게.
- 종이 섬유: 셰이더의 늘인 노이즈로 만들지 않는다(4방향 직선 해칭이 된다). 시작할 때 Canvas2D 로 한 번 그린 섬유 텍스처를 쓴다: 짧은 2차 베지어 곡선 1,200개, 길이 0.02~0.08 짧은 변, 방향 완전 무작위, 굵기 0.5~1.2px, 불투명도 3~7%. 먹 흡수에 대한 섬유 영향은 ±6% 이내(먹 속에서 섬유가 검은 줄로 보이면 실패). 가장자리 비네팅 6%.
- 종이 얼룩: 같은 텍스처에 아주 큰 부드러운 얼룩 40개(반지름 0.12~0.5 짧은 변)를 밝은 것 반, 어두운 것 반으로 섞어 그린다. 각 불투명도 1~2%. 종이 전체 평균 밝기는 #EDE5D5 에서 ±2% 안에 머문다(얼룩 때문에 한지가 회색으로 보이면 실패).
[장면]
- 시작 화면: 첫 프레임을 그리기 전에 시뮬레이션을 9.9초(594스텝) 미리 진행해 둔다(그동안은 그리지 않는다). 그러면 t=0 에 이미 방울 여섯이 번져 화면의 약 5분의 1을 휘감고 있고, 다음 방울이 t≈0.3초에 떨어져 첫 1초 안에 착지 순간이 보인다. 빈 한지나 그림자 점 하나로 시작하지 않는다.
- 방울 시간표: n번째 방울(n = 0, 1, 2…)은 시뮬레이션 시각 0.6초 + n × [바꿀 곳]의 간격에 착지한다(미리 진행한 시간도 시뮬레이션 시각에 들어간다). 위치: R2 저불일치 수열 x = frac(0.5 + n·0.7548777), y = frac(0.5 + n·0.5698403) 에 ±0.06 지터(시드 고정), 가장자리 12% 안쪽으로 사상. 화면 전체를 고르게 돈다.
- 다섯 방울 중 하나는 주홍 먹.
- 한 방울의 흐름: 예고 그림자(0.35초) → 착지 순간 울퉁불퉁한 완전 검정 덩어리 → 터지며 버섯처럼 말린다 → 짙은 남흑 줄기는 오래 남고 회청 베일은 걷힌다.
- 순환: 위 소산이면 덮인 비율(아래 [구현]의 정의)이 스스로 0.2 안팎(0.15~0.25)에서 평형을 이룬다. 안전장치로, 덮인 비율이 62%를 넘으면 6초에 걸쳐 먹 소산을 0.6/초로 올렸다가 되돌린다(갑자기 지우지 않는다).
- 조작: 끄는 동안 매 프레임, 포인터 주변(반지름 0.03 짧은 변 가우시안) 물의 속도를 「포인터 이동 속도 × 1.5」 쪽으로 30%씩 끌어당긴다(v = mix(v, 목표, 0.3 × 가우시안), 목표 속도 상한 9000 픽셀/초). 끄는 동안 먹이 조금(양 0.05) 묻어난다.
- 조작: 짧게 클릭·탭하면 그 자리에 위의 「먹 한 방울」 전체가 떨어진다(예고 그림자 0.35초 포함).
- 화면 오른쪽 아래에 작은 글씨로 「먹 비우기」 버튼 하나만 둔다(누르면 순환처럼 천천히 맑아진다). 그 밖의 글자는 화면에 없다.
[구현]
- HTML 파일 하나로 만든다. 외부 파일·글꼴·라이브러리·네트워크 요청을 쓰지 않는다(미리보기에서 막히거나 느려진다).
- 첫 <script> 맨 앞에 CONFIG 객체를 두고 [바꿀 곳]의 값과 이 글에 나온 숫자(시간표·크기·색·세기)를 이름 붙여 모은다. 나중에 숫자만 바꿔 다듬을 수 있게.
- 그림은 시간 t(초)만으로 계산하는 함수 render(t) 로 그린다. requestAnimationFrame 의 타임스탬프나 performance.now() 로 t 를 구한다. setTimeout·setInterval·CSS 애니메이션·transition 으로 움직이지 않는다(프레임마다 속도가 달라지고, 다시 재생할 때 어긋난다). 시뮬레이션처럼 상태가 쌓이는 작품은 고정 시간 간격으로 상태를 진행하되 그 진행도 타임스탬프로만 정한다.
- 난수는 시드 고정 난수(mulberry32 등)만 쓴다. Math.random 은 쓰지 않는다(매번 다른 화면이 나온다).
- 캔버스 내부 해상도는 화면비에 맞춘 기준 크기로 고정하고, 창 크기에 맞춰 화면비를 지키며 가운데에 꽉 차게 보이게 한다(남는 곳은 배경색). 스크롤이 생기지 않게 한다. devicePixelRatio 는 그리는 선명도에만 반영한다.
- 글자는 시스템 글꼴만 쓴다: 'Pretendard', 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans KR', sans-serif. 붓글씨·손글씨 느낌은 글꼴이 아니라 획을 그려서 낸다.
- 길이가 정해진 작품은 끝나면 처음과 같은 화면으로 돌아가 이음매 없이 반복한다.
- 모든 함수·상수·셰이더 문자열을 먼저 정의하고, 시작(초기화와 첫 requestAnimationFrame)은 스크립트 맨 끝에서 한 번만 호출한다. 정의되기 전에 쓰면 첫 화면에서 멈춘다.
- 이 작품만의 규칙: 상태가 쌓이는 유체라, 시뮬레이션 진행은 위 시간 규칙 대신 [시뮬레이션]의 「고정 시간 간격 dt = 1/60초로 매 프레임 한 번」을 따른다. 끝없이 이어지는 작품이라 반복 이음매 규칙은 해당하지 않는다.
- 미리 진행: 시작 호출 안에서, 첫 requestAnimationFrame 전에 한 번에 돌린다. 60스텝씩 나눠 돌리고 덩어리마다 gl.finish() 뒤 performance.now() 로 걸린 시간을 잰다. 첫 덩어리가 0.25초를 넘으면(느린 기기) 먹 해상도를 512로 낮추고 이어 간다. 미리 진행 전체가 3초를 넘기면 거기서 멈추고 시작한다(첫 화면까지 오래 기다리게 하지 않는다).
- WebGL2 우선(RGBA16F 텍스처 + EXT_color_buffer_float), 안 되면 WebGL1 + OES_texture_half_float(+ _linear). 둘 다 안 되면 화면 가운데에 「이 기기에서는 WebGL이 필요합니다」 한 줄.
- 성능: 노트북 60fps 목표. 평균 프레임이 45fps 아래로 2초 이상 떨어지면 먹 해상도를 한 단계(1024→768→512) 낮춘다.
- 덮인 비율의 정의: 먹 텍스처를 64×36 칸으로 줄여 읽었을 때, 먹 양(두 채널 합)이 0.06 을 넘는 칸의 비율. 60스텝마다 한 번 잰다.
- 스스로 대조: 아래 합격 기준을 코드로 재서 미리 진행이 끝난 직후 한 번, 그 뒤 10초마다 console.log 로 [시각, 덮인 비율, 미리 진행 스텝 수, 먹 해상도]를 찍는다. 기준을 벗어나면 console.warn 으로 어느 기준인지 적는다.
· t=0(미리 진행 직후) 덮인 비율 ≥ 0.15
· 첫 착지 시각 t ≤ 1초
· 10초 이후 덮인 비율 0.15~0.3 (0.3 을 넘으면 회청 베일이 화면을 덮는다는 뜻 — 압력 기울기 배율부터 확인)
· 미리 진행 스텝 수 = 594 (느린 기기에서 줄었으면 그 수와 걸린 시간을 적는다)
[하지 말 것]
- 방사형 힘에 sin(n·θ) 같은 각도 변조(꽃잎·lobe·wobble)를 곱하지 않는다, 아주 작게라도 — 원대칭 성분은 압력 투영이 거의 다 지우고, 각도 변조 성분은 투영을 통과해 매 스텝 쌓인다. 진폭을 줄여도 투영 뒤 남는 흐름 대부분이 그 무늬라서 먹이 n갈래 별(X 자)이 된다.
- 압력 기울기에 0.5 를 곱해 빼지 않는다(교과서 식이어도) — 25회 야코비로는 발산이 덜 지워져 먹이 벽에 붙어 위쪽 테두리에 줄이 생기고, 회청 베일이 화면 절반을 덮고, 착지 중심이 1초 넘게 꽉 찬 검은 원반으로 남는다. 이 글의 소산·희석 숫자는 두 배로 빼는 쪽에 맞춘 값이다.
- 터지는 힘을 압력 투영 앞에 넣지 않는다 — 투영이 지워 버려 먹이 터지지 않는다.
- 빈 한지나 그림자 점 하나로 시작하지 않는다 — 첫 1초에 아무것도 없으면 보는 사람은 멈춘 화면으로 여기고 떠난다.
- 중심 먹을 가우시안 하나로, 위성 방울을 같은 크기로 찍지 않는다 — 착지 순간 완벽한 원과 똑같은 점들이 보여 컴퓨터가 찍은 도장처럼 읽힌다.
- 가장자리 소용돌이를 고른 각도로 놓거나 크기·세기·부호를 같게 맞추지 않는다 — 고르게 놓으면 다시 톱니바퀴 같은 대칭 무늬가 되고, 크기가 같으면 먹이 아니라 오돌토돌한 노이즈로 보인다.
- 와도 강화를 24 이상으로 올리지 않는다 — 격자 눈금 크기의 고른 컬이 화면에 깔려 콜리플라워 같은 노이즈가 된다.
- 방울 전체 회전을 150 이상으로 올리지 않는다 — 갈고리가 전부 한쪽으로 말려 바람개비 모양이 된다.
- 희석을 빼지 않는다 — 퍼지는 흐름에서 먹 양이 20배로 불어나 화면이 새까맣게 덮인다.
- 발산을 ±2.5칸보다 촘촘하게 읽지 않는다 — 격자 점무늬가 생긴다.
- 끄는 동안 속도를 매 프레임 더하지 않는다 — 속도가 상한까지 쌓여 물이 저어지지 않고 먹을 밀어내는 둥근 둑(불도저 자국)이 생긴다.
- 수면 파문 고리를 그리지 않는다 — 기본 대비에서는 보이지 않고, 보이면 먹 가장자리에 겹친 「그린 원」으로 읽힌다.
- 먹을 덧셈 블렌딩·발광으로 그리지 않는다 — 먹은 종이가 돌려주는 빛을 빼앗아 어두워지는 것이라, 더하면 빛나는 연기처럼 떠 보인다.
- 종이 섬유를 셰이더의 늘인 노이즈로 만들지 않는다 — 4방향 직선 해칭이 된다.
- 섬유가 먹 흡수를 ±6% 넘게 흔들지 않게 한다 — 먹 속에서 섬유가 검은 줄로 보인다.
- 종이 얼룩을 어두운 쪽으로 치우치게 그리지 않는다 — 한지가 지정색보다 어두운 회갈색 구름으로 덮여 더러워 보인다.
- 가장자리 4% 띠의 추가 소산을 빼지 않는다 — 먹이 벽에 붙어 액자처럼 짙은 띠가 생긴다.
- 덮인 비율이 높아도, 「먹 비우기」를 눌러도 먹을 한 번에 지우지 않는다 — 물속 먹은 갑자기 사라지지 않아서 장면이 끊겨 보인다.
- 네온색·글로우·무지개색·반짝이 파티클을 쓰지 않는다 — 한지·먹·주홍 밖의 빛이 들어오면 먹이 아니라 화면 효과로 읽힌다.
- 대칭 무늬를 만들지 않는다 — 「컴퓨터가 만든 티」가 나는 순간 진짜 먹으로 보이지 않는다.
- 「먹 비우기」 버튼 말고는 제목·설명·프레임 수 같은 글자를 화면에 띄우지 않는다(WebGL 안내 한 줄은 예외) — 종이와 먹만 보여야 한다. 스스로 대조 결과는 화면이 아니라 콘솔에만 낸다.
사용 방법
필요한 것: claude.ai 계정 — 무료 계정에서도 Claude Opus 5.5 를 고를 수 있습니다
- claude.ai 에서 새 대화를 엽니다.
- 모델 메뉴에서 Claude Opus 5.5 를 고르고, 같은 메뉴의 Effort(답변 깊이)를 High 로 둡니다.
- 복사한 프롬프트를 붙여 넣고 전송합니다. 결과로 나온 HTML 파일을 브라우저로 열면 재생됩니다.
- 권장 모델
- Claude Opus 5.5 · Effort High
- 화면비
- 16:9 (가로)
- 재생 길이
- 12초
- 결과물
- HTML 파일 하나 · 따로 설치할 것 없음
- 영상 파일
- 해당 없음
추가 요청 예시
결과가 나온 뒤 같은 대화에서 이어서 요청하면 해당 부분만 수정됩니다.
- 먹 색을 짙은 쪽빛으로 바꾸고, 주홍 방울은 빼 줘.
- 먹이 떨어지는 간격을 3초로 늘려서 한 방울씩 더 오래 볼 수 있게 해 줘.
- 분위기를 더 고요하게 — 물이 저절로 흐르는 힘과 먹이 떨어질 때 퍼지는 힘을 절반으로 줄여 줘.
감상