Community코딩 & 개발github.com

webgl-form

Stripe 스타일의 히어로 웨이브를 Three.js r178로 구축합니다. stripe.com의 접힌 시트(두 겹으로 접힌 두껍고 둥근 모서리의 평면)를 stripe.com의 설정과 함께, Stripe의 조명 없는 셰이딩(시트를 따라 칠해진 팔레트, 긴 실키한 줄무늬, 창백한 밑면)으로 구현하며, 각 부분이 각자의 노이즈에 따라 움직입니다.

webgl-form란 무엇인가요?

이 스킬은 사용자가 3D 히어로 비주얼, 'Stripe 웨이브', 셰이더 리본, WebGL 모델 또는 형태, 또는 아이디어나 브랜드를 위한 히어로 아트를 요청할 때 사용됩니다. 입력은 형태가 아닌 의미를 전달해야 합니다. 제품의 기능(한 문장), 브랜드 컬러, 아트가 위치할 곳을 물어보고, 프롬프트가 없으면 코드에서 색상을 읽어 Stripe의 라이트 히어로 웨이브를 사용합니다. 아이디어는 웨이브의 색상, 크롭, 설정을 변경하지만 형태는 절대 변경하지 않습니다. 이 스킬은 Claude Code, Cursor, Codex와 같은 플랫폼에서 사용할 수 있습니다. Three.js 애플리케이션 내에서 Stripe 스타일의 웨이브를 구현하는 방법에 대한 포괄적인 지침을 제공합니다. 여기에는 정점 셰이더에서 접힌 시트를 구축하고, Stripe의 세 가지 비틀림을 적용하며, 특정 노이즈 웨이브와 배치 규칙을 따르는 과정이 포함됩니다. 스킬은 아이디어를 설정에 매핑하는 데 중점을 두며, 사용자가 제안한 명명된 형태를 문자 그대로 해석하는 것을 피하고 대신 의미(예: 토네이도는 힘을 의미할 수 있음)를 해석하여 웨이브의 설정을 조정합니다. 또한 Stripe 웹사이트의 정확한 설정을 가진 다섯 가지 사전 정의된 웨이브 사전 설정을 포함하며, 조명 없는 셰이딩, 팔레트 페인팅, 페이지 배치에 대한 엔지니어링 규칙을 정의합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Rahuchpred/raha/tree/main/skills/webgl-form

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

WebGL form

form은 웨이브입니다: stripe.com의 접힌 시트, stripe.com이 그리는 그대로. 여러 시도 끝에 나온 사용자의 판단: "저는 웨이브가 정말 좋은 형태라서 웨이브만 마음에 들어요. 웨이브가 제가 원했던 바로 그겁니다." 시도된 다른 모든 형태(링, 매듭, 스프링, 나선형 깔때기, 엉킨 시트)는 거부되었습니다. 따라서 아이디어는 절대 새로운 형태가 되지 않습니다. 각자의 색상, 크롭, 설정을 가진 웨이브가 됩니다.

파일설명
reference/stripe-three.js엔진입니다. Three.js r178: 정점 셰이더로 구축된 접힌 시트, Stripe의 비틀림(회전 목록), Stripe의 조명 없는 셰이딩, 칠해진 팔레트, 후처리 패스, 그리고 아래 다섯 가지 작동 웨이브가 있는 TAKES / PRESETS. 복사한 다음 프리셋을 추가하세요.
reference/stripe-notes.mdstripe.com의 히어로 웨이브가 출시되는 그대로입니다: 접힘 지오메트리, 셰이더, 카메라, 네 가지 웨이브의 설정. 조정하기 전에 읽어보세요.
reference/twist-ribbon.js, reference/nib-ribbon.ts오래된 일반 WebGL2 리본(OpenRouter, OpenEvidence). 이미 실행 중인 프로젝트에만 해당됩니다.
reference/ReactMount.tsx폴백이 있는 React/Next 마운트입니다.

0. 무엇을 물어볼 것인가

프롬프트는 의미를 전달하며, 절대 형태를 전달하지 않습니다. 형태는 실패였습니다: 문자 그대로 구축된 명명된 모든 형태(뫼비우스 링, 매듭, 스프링, 토네이도)는 3D 클립 아트로 나왔습니다. OpenRouter 리본이 작동한 이유는 의미("하나의 엔드포인트로 들어오는 많은 모델")가 제품의 그림이 아닌 설정(시트가 가장자리로 향하는 위치)이 되었기 때문입니다.

한 메시지에서 최대 세 개를 물어보세요:

  1. 아이디어, 한 문장으로: 제품이 하는 일, 또는 아트가 전달해야 할 한 가지. ("하나의 엔드포인트를 통한 모든 모델.")
  2. 색상: 브랜드의 색상, 또는 "코드에서 읽어오기"(globals.css의 토큰, Tailwind 테마, 로고의 색상).
  3. 위치: 히어로 밴드(카피 아래나 주변), 셀, 카드; 밝은 페이지 또는 어두운 페이지.

프롬프트가 전혀 없는 것도 유효한 사용입니다: 코드에서 색상을 읽고, Stripe의 라이트 히어로 배치에서 wave 프리셋을 사용하고, 한 줄로 그렇게 말하세요.

명명된 형태("토네이도 만들기"): 형태를 구축하지 마세요. 의미(토네이도: 상승, 회전, 힘)에 대한 힌트로 읽고 아래 설정에 매핑하세요. 스킬이 웨이브를 유지하는 이유를 한 줄로 사용자에게 알리세요. 사용자가 계속 고집하면, 웨이브 옆에 추가 테이크로 형태를 구축하고 레이블을 붙여 비교할 수 있게 하세요.

의미에서 설정으로 (규칙이 아닌 시작점):

아이디어의 느낌시작 프리셋변경 사항
차분함, 신뢰, 돈, 건강deep속도 4e-5, 차갑거나 중성적인 팔레트, 넓은 크롭
다수가 하나로, 집중, 엔드포인트wave가장자리로 향하는 늘어짐(집힘)을 카피 아래나 옆에 배치
에너지, 실시간, 속도petal 또는 fold속도를 8e-5까지, 따뜻한 팔레트
변화, 양면, 전환turn롤오버로 양면이 보임
특별한 것 없음wave브랜드 팔레트만

출력: 테이크 페이지에 두세 개의 테이크, 동일한 웨이브 패밀리의 다른 프리셋, 크롭 또는 팔레트. 사용자가 하나를 선택하면 나머지를 삭제합니다.

1. 형태

  • 접힌 시트: 400 x 400 평면(128 x 256 세그먼트)을 반으로 접습니다: 상단 레이어는 32유닛 스트립이 반원통(둥근 접힘)으로 구부러지고, 하단 레이어는 아래로 접혀 끝에서 4유닛, 중간에서 2유닛 떨어져 있습니다. 두 번의 1/4 회전으로 세워짐: 길이는 x축, 두께는 y축, 너비는 z축. 두껍고 둥근 모서리, 절대 가는 선 없음. 정점 셰이더에서 uv로 구축(folded(uv)), 따라서 법선이 정확합니다.
  • Stripe의 세 가지 비틀림이 형태를 만듭니다: 대각선 축 (.5, 0, .5) 및 (0, .5, .5)에 대한 회전, 각각 Stripe의 소프트 스텝 exp2(-exp2(n) * pow(x, n))으로 너비(u) 또는 길이(v)를 따라 램핑됩니다. 엔진에서: Stripe의 숫자로 stripeTwists([x, y, z], [powX, powY, powZ]). x 비틀림은 길이를 따라 노이즈에 의해 표류합니다. 이것이 노이즈 웨이브와 함께 모든 움직임입니다. 부분은 움직이지만 전체는 절대 회전하지 않습니다.
  • 노이즈 웨이브: p.y += amount * noise(x * fx + t, z * fz + t).
  • Stripe의 프레임 내 배치: 픽셀 단위의 1392px 너비 캔버스, (100, 0, 5000)에 있는 직교 카메라가 y축을 기준으로 0.02 rad 회전; 모든 숫자는 캔버스 너비 / 1392로 스케일링됩니다. 항상 크게 그리고 프레임에 의해 크롭됨, 절대 작거나 떠 있지 않음.
  • 속도: Stripe의 시계, 밀리초당 4e-5에서 8e-5. 의도적으로 느림.

2. 작동하는 다섯 가지 웨이브

네 가지는 stripe.com이 출시하는 웨이브이며 정확한 설정(비틀림 x, y, z; 거듭제곱; 노이즈 웨이브; 배치; 글로우; 속도)을 가지고 있습니다. 다섯 번째는 한 번의 회전을 추가합니다.

프리셋출처비틀림 x, y, z / 거듭제곱노이즈 웨이브회전; 스케일; 위치글로우속도, 오프셋
waveStripe의 라이트 히어로-0.65, 0.41, -0.58 / 3.63, 0.7, 3.950.005831, 0.016001, -7.821-0.4496, -0.1176, 1.8744; 9, 8, 5; 380, -301.7, -11.11.98, 0.806, 0.8344e-5, 17500
deepStripe의 다크 히어로, 흰색 위에 그림-0.055, 0.077, -0.518 / 3.95, 5.85, 6.330.003234, 0.00799, 6.051-0.1596, -0.2836, -2.8156; 10, 10, 7; -24.3, -56.4, -11.10.6, 0.589, 14e-5, 1150
foldStripe의 빌링 히어로, 셀에 맞게 회전-0.424, 0.024, -1.312 / 1.81, 0.94, 4.760.005, 0.0212, 6.68-0.666, -0.0314, 1.9; 6.05, 8.4, 6.99; 50, -100, -11.11.55, 1.174, 0.9725.25e-5, 17500
petalStripe의 작은 악센트 웨이브, 확대 및 회전0.059, 0.32, -0.397 / 3.63, 0.44, 5.990.005831, 0.016001, -7.821-2.8756, 3.0959, -1.6; 9, 9, 9; 0, -50, -11.13.86, 0.923, 18e-5, 2275
turn라이트 히어로, 완전히 뒤집힘 (작동하는 유일한 추가 회전)라이트 히어로의, 더하기 LENGTH (1, 0, 0) along v, 2pi, drift 0.15라이트 히어로의라이트 히어로의라이트 히어로의라이트 히어로의

굵은 숫자는 Stripe의 자체 배치와 다릅니다: Stripe는 자체 프레임을 위해 해당 웨이브를 배치했으므로, 더 작은 셀에서는 평평한 패치로 크롭되거나 작게 떠 있습니다. 다시 배치하고, 절대 다시 형태를 만들지 마십시오: 다른 프레임에 맞추려면 회전, 스케일 및 위치만 변경하십시오(HTML의 data-overrides).

3. 셰이딩: Stripe 고유의, 조명 없음

실제 stripe.com 히어로에는 조명이 전혀 없습니다. 그래서 플라스틱처럼 보이지 않고 밝고 광택이 나 보입니다. 그 표면은 다음과 같습니다:

  1. 시트의 (u, v)에서 팔레트.
  2. 길이를 따른 길고 가는 streaks: n0 = noise(u * 0.1, v * 0.5), n1 = noise(u * (600 + 300 n0), v * 4 n0) (가로로 매우 가늘고, 세로로 거의 일정), n1 * 0.2 to 0.26 * (1 - blue * 0.9) * pdy * edge로 추가됨, 여기서 edge = 1 - pow(4u(1 - u), 3) (열린 가장자리 쪽으로 가장 강함). 따뜻한 색상에서 가장 잘 보입니다. 모두 파란색 팔레트의 경우 파란색 페이드를 약 0.4로 낮추십시오.
  3. 글로우 항 pdy: dFdy(v) * resolution.y * amount, -1..1에서 0..1로 매핑, 거듭제곱으로 올림, 램프로 smoothstep. 부호는 시트의 두 면을 구분합니다. 0에 가까우면 시트가 접히는 중입니다.
  4. 대비, 채도, 색조, 그다음 + (1 - pdy) * 0.25: 다른 면과 접힘 부분이 창백해집니다. 이것이 Stripe의 접힘 부분에 있는 크리미한 띠입니다.
  5. 불투명, 깊이 테스트됨. 후처리 패스: 중간의 선명한 띠를 피한 0.02 rad 회전 블러, 그다음 색상이 있는 곳에 그레인(1.1). 그레인은 Stripe의 정적 디더입니다: color + mix(1, -1, random(gl_FragCoord.xy * 0.01)) * 4/255 * amount. 프레임에서 프레임으로 절대 변하지 않습니다. 매 프레임마다 다시 무작위화되는 그레인은 반짝이고 노이즈로 읽히며("Stripe에 비해 노이즈가 너무 많음"), 비디오에서는 파일 크기도 몇 배로 증가시킵니다.

그려진 선, 움직이는 빛, 일반 조명, 주름 하이라이트 없음: 엔진의 이전 lit 셰이딩은 옵션(shading: "lit")으로만 유지되며 기본값이 아닙니다.

4. 팔레트

Stripe가 실행하는 방식으로 칠하고, 무작위 얼룩이 아니어야 합니다(무작위 얼룩은 보이는 시트의 대부분에 하나의 평평한 색상을 제공했습니다):

  • 길이(v)를 따라, 주요 그라데이션. 라이트 히어로: 라벤더 블루 #9fb6ff, 바이올렛 #a978ff, 마젠타 #e05cff, 핫 핑크 #ff4fa8, 오렌지 #ff7a2a, 앰버 #ffa318.
  • 너비(u)를 따라, 열린 가장자리 쪽으로 틴트(약 75%, 각면에서 u = 0.22까지 페이드 아웃): 라이트 히어로의 경우 라벤더 #a9b6ff.
  • 몇 개의 희미한 얼룩(14개, 25%)은 다양성을 위해서만.
  • 엔진의 palette(along, edge, blobs)가 이것을 구축합니다. 다른 작동 세트: 오션(파란색에서 시안), 더스크(오렌지, 핑크, 바이올렛), 라임(청록, 녹색, 노랑, 오렌지), 엠버(핑크, 빨강, 오렌지, 노랑).
  • 색상은 브랜드의 색상이거나 Stripe와 유사해야 합니다. 장식용이며, 절대 데이터가 아닙니다.

5. 페이지 내 배치

웨이브 위에 카피 복사 (Stripe의 오버랩)

2026-10-22에 stripe.com에서 측정됨. 웨이브가 헤드라인 아래에서 실행될 때, Stripe는 웨이브를 마스킹하지 않고 단어를 덮지 않도록 합니다. 카피를 두 번 그립니다:

  1. 캔버스 아래: 일반 색상의 카피(Stripe: 헤드라인 네이비 #061b31, 본문 회색). 웨이브가 그 위를 지나갈 때, 웨이브가 카피를 숨깁니다.
  2. 캔버스 위 (z-index가 웨이브 레이어 위): 동일한 카피, 동일한 크기와 위치, aria-hidden, mix-blend-mode: hard-light와 반투명 틴트 색상(Stripe: 헤드라인 rgb(45, 37, 100), 진한 바이올렛; 본문 rgba(0, 14, 255, 0.5), 반투명 파란색). 흰색 페이지 위에서는 일반 텍스트로 읽힙니다. 웨이브 위에서는 문자가 웨이브의 색상을 취하므로 읽기 쉽고 실크에 인쇄된 것처럼 보입니다.

규칙:

  • 상단 카피의 틴트를 브랜드에서 선택: 헤드라인 색상의 진하고 채도가 높은 버전과 본문용 반투명 브랜드 블루(또는 악센트). 웨이브가 가장 밝은 스크린샷을 확인하세요: 모든 단어가 여전히 읽을 수 있어야 합니다.

  • 두 카피는 정확히 일치해야 합니다(동일한 요소 스타일, 동일한 랩): 하나의 소스에서 빌드하고 하나의 그리드 셀(grid-area: 1 / 1)에 쌓아서 글꼴이나 너비 변경이 둘 다 움직이도록 합니다.

  • 스크린 리더는 하단 카피만 받습니다. 상단 카피는 aria-hidden이며 포인터 이벤트를 받지 않습니다. 버튼과 링크는 하단 레이어에 유지되며 캔버스로 덮이지 않아야 합니다(웨이브 경로 밖에 두거나 버튼만 그 위로 들어 올리십시오).

  • 축소된 모션과 정지 이미지 폴백은 두 카피를 모두 유지합니다. 블렌드는 정지 이미지 위에서도 작동합니다.

  • 절대 흰색 판이나 마스크로 카피가 웨이브를 피하게 하지 마십시오. 이중 카피가 존재하는 이유가 바로 그 모양을 피하기 위해서입니다.

  • 웨이브는 셀 또는 히어로 밴드를 채우거나 크롭합니다. 캡션은 작은 페이지 색상 칩 위에 있습니다.

  • 절대 내비게이션 아래나 다음 섹션 안으로 들어가지 않습니다. 크롭된 웨이브가 밴드의 상단과 만나는 곳에서는 CSS 마스크로 페이드 아웃하고, 카피와 만나는 곳에서는 위의 이중 카피를 사용합니다.

  • 아트 내부에 레이블, 숫자 또는 그리드 선이 없습니다.

6. 엔지니어링 규칙

  • Three.js r178이 프로젝트에 설치되고, 임포트 맵("three": "/node_modules/three/build/three.module.js")으로 로드됩니다.
  • THREE.ColorManagement.enabled = false; 팔레트 NoColorSpace; ShaderMaterial in GLSL1 스타일.
  • failIfMajorPerformanceCaveat: true; 실패 시 동일한 웨이브의 정지 이미지. 프레임 시간을 관찰하세요: 후처리 패스를 드롭하고, 그다음 DPR을 드롭하고, 그다음 정지 프레임에서 중지합니다.
  • DPR은 2로 제한됨; ResizeObserver; 화면 밖 및 숨겨진 탭에서 일시 중지; 축소된 모션은 하나의 정착된 프레임을 그립니다. 포인터 반응성 없음.
  • 페이지당 최대 약 13개의 웨이브; 16개를 넘으면 브라우저가 컨텍스트를 드롭합니다.
  • GLSL 변수를 step, mix 또는 fract로 명명하지 마십시오.

7. 워크플로우

  1. 입력 받기(섹션 0): 아이디어, 색상, 위치. 프롬프트 없음: 코드에서 색상, wave 프리셋. 아이디어를 프리셋, 크롭 및 팔레트에 매핑하고, 절대 새로운 형태로 매핑하지 않습니다.
  2. 실제와 비교: stripe.com의 히어로를 1440x900에서 스크린샷하고, 우리의 것을 Stripe의 정확한 프레임(1392 x 761, x 337 위치)의 캔버스에서 렌더링하고, 동일한 크롭에서 둘을 비교합니다. 텍스처와 색상은 이렇게 판단되며, 기억에 의존하지 않습니다.
  3. 여러 웨이브가 있는 페이지의 경우 위의 프리셋을 사용하여 각 프레임에 맞게 재배치하고, 테이크 페이지에 대안을 표시합니다.
  4. 전체 크기(Headless Chrome)에서 확인: 콘솔이 깨끗하고 모든 캔버스가 구축됨; 1440 및 375; 4초 간격의 두 프레임을 분기별로 비교(고르지 않은 변화: 부분 이동; 고른 변화: 회전); 웨이브가 프레임을 채웁니다.
  5. 눈에 보이는 변경 사항을 설명하는 메시지와 함께 커밋합니다.

거부됨, 반복하지 마십시오

  • 명명된 형태를 문자 그대로 받아들이는 것. "토네이도 만들기"와 같은 프롬프트는 의미에 대한 힌트이지 지오메트리가 아닙니다.
  • 웨이브 이외의 모든 형태. 링, 매듭, 스프링 및 경로를 따라 휩쓸린 튜브("다른 것들은 정말 멋져 보이지 않음"), 그리고 강한 회전에 의해 다른 형태로 밀려난 접힌 시트: 나선형 깔때기, 감긴 코일, 엉킴("엉킴, 코일 및 깔때기는 정말 나쁨"). 부드러운 롤오버(turn)만 "괜찮을 수도 있음"으로 통과했습니다.
  • 조명이 있는 음영 처리된 시트: Stripe의 조명 없는 표면 옆에서 플라스틱처럼 읽힙니다.
  • 무작위 얼룩의 팔레트: 하나의 평평한 색상이 보이는 시트를 채웁니다.
  • 단일 레이어 시트: "얇은 측면이 보입니다."
  • 전체 개체 회전: "일부 부분이 아닌 전체가 움직였습니다."
  • 움직이는 빛 선: "그것은 OpenRouter 전용이었고, 여기서는 Stripe를 모방합니다."
  • 프레임 중앙에 떠 있는 작은 웨이브.
  • 투명한 것에 대한 일반 알파 블렌딩: 이음새.
  • 그려진 선, 노드 및 와이어 다이어그램, 그리드 선, 레이블

관련 스킬