Communitygithub.com

immersive-3d-site

실시간 Three.js 3D 장면과 실제 HTML이 결합된 몰입형 웹사이트를 구축합니다. 스크롤과 포인터로 제어됩니다.

immersive-3d-site란 무엇인가요?

이 스킬은 사용자가 '3D 웹사이트', '몰입형 웹사이트', 'Three.js 랜딩 페이지' 등을 요청할 때, 단순한 3D 동영상이 아닌 실제로 작동하는 3D 웹페이지를 제작하도록 돕습니다. 스크롤이 타임라인이 되고 커서가 보조 카메라가 되어, 방문자는 실시간 3D 장면 위에 배치된 실제 HTML 텍스트를 읽고 선택할 수 있습니다. Claude Code, Cursor, Codex 등 모든 AI 에이전트 플랫폼에서 사용 가능하며, 빌드 단계 없이 정적 사이트로 결과물을 제공하고 API 키도 필요하지 않습니다. 이 스킬은 4가지 이상의 다양한 장치(예: 유리/금속 오브젝트, 파티클 모프, 카메라 레일, 분해도)를 사용하고, 하나의 '최고의 순간'을 설계하며, 3D가 콘텐츠의 메시지를 전달하도록 초점을 맞춥니다. 또한 데스크톱과 휴대폰에서 모든 스크롤 위치를 스크린샷으로 찍어 품질을 검증합니다.

지원 대상~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/automatorsplus/immersive-3d-site-skill/tree/HEAD/.claude/skills/immersive-3d-site

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

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

문서

immersive-3d-site은(는) 무엇을 하나요?

3D가 동영상이 아닌 실시간으로 구현된 페이지입니다. 방문자의 스크롤이 타임라인이 되고 커서는 두 번째 카메라가 됩니다. 실제 텍스트는 위에 배치되어 읽을 수 있고 선택 가능하며, WebGL 캔버스는 그 뒤에 있습니다.

전달하는 결과물: BRIEF.md가 포함된 빌드 폴더, 하나의 실제 index.html, 그 옆의 엔진 파일, 데스크탑·휴대폰·축소 모션 스크린샷 스트립, 그리고 확인한 사항과 확인하지 못한 사항에 대한 간단한 보고서입니다.

이런 페이지가 실패하는 이유

대부분의 "3D 웹사이트"는 페이지 전체에 하나의 트릭만 사용합니다: 텍스트가 페이드 인되는 회전하는 모델. 세 번째 섹션에 도달하면 방문자는 모든 것을 보고 스크롤을 멈춥니다. 다음 네 가지 규칙이 이를 방지합니다:

  1. 각 장면은 다른 무언가를 합니다. 참조/scene-kit.md에서 최소 네 가지 이상의 다른 장면 장치를 사용하고, 같은 장치를 연속으로 두 번 사용하지 마세요.
  2. 하나의 정점. 한 장면은 누군가가 친구에게 설명하는 순간입니다. 가장 많은 스크롤 공간, 최고의 장면을 할당하고, 그 전에 더 조용한 장면을 배치하여 효과를 극대화하세요.
  3. 3D는 메시지를 전달합니다. 모든 장면은 주제에 대한 진실(무엇으로 만들어졌는지, 어떻게 작동하는지, 어떤 느낌인지)을 보여줍니다. 장식에 불과한 장면은 삭제됩니다.
  4. 모든 스크롤 위치에서 텍스트를 읽을 수 있어야 합니다. 어떤 프레임에서든 텍스트 줄이 장면 위에서 읽기 어렵다면, 텍스트를 움직이는 것이 아니라 장면을 움직입니다.

0단계: 브리프

사용자가 이미 제공한 내용을 재사용합니다. 사용자가 전체 브리프를 제공했거나 "당신의 판단에 맡깁니다"라고 말한 경우, 직접 BRIEF.md를 작성하고 "창의적 위임에 따라 작성됨"이라고 표시한 후, 아래 모든 질문에 브랜드의 어조로 직접 답변하고 진행합니다. 그렇지 않으면 여덟 가지 질문을 모두 한 번에 묻습니다. 실제 질문으로, 당신이 만든 메뉴가 아닌 방식으로:

  1. 이것은 무엇이고, 누구를 위한 것이며, 마지막에 방문자가 무엇을 해야 합니까? 하나의 행동, 모든 곳에서 사용되는 하나의 레이블.
  2. 3~5단어로 표현되는 느낌, 그리고 웹사이트가 아닌 참고 자료(영화, 게임, 앨범 커버, 상점) 최대 세 개. 웹사이트를 언급하면 결국 다른 사이트를 복사하게 됩니다.
  3. 방문자의 관점에서 본 여정: 방문자가 처음, 그 다음, 마지막으로 만나는 것.
  4. 어디가 차분해야 하고 어디가 강렬해야 하는지.
  5. 각 단계에서 방문자가 어떻게 느껴야 하며, 기억해야 할 한 순간은 무엇인지. 참조/feel.md를 참조하세요.
  6. 이 사이트가 그들이 본 어떤 사이트도 하지 못한 한 가지 일. 시그니처 움직임의 씨앗입니다. 진짜 답변을 요구하세요. "기억에 남는 것"은 답변이 아닙니다.
  7. 프리미엄-미니멀에서 얼마나 떨어져 있는지: 참조/structures.md의 범위를 제공합니다.
  8. 하나의 연속된 세계인가, 아니면 별도의 장면인가? 가장 큰 구조적 분기점이며, 그들의 결정입니다. 추가로: 이미 가지고 있는 것(로고, 색상, 글꼴, 제품 사진, .glb 3D 모델).

빌드 폴더에 BRIEF.md를 작성하고 사용자의 답변을 그들의 언어로 기록한 후 다음을 추가합니다:

  • 여정: 4~7개의 비트, 각각 방문자가 알거나 느끼는 것이 변화합니다.
  • 느낌 곡선: 각 비트당 한 줄, 느낌과 이를 유발하는 화면상의 요소. 인접한 두 개가 같지 않아야 합니다.
  • 정점: 방문자가 이 사이트에 대해 말할 문장과 그것이 속한 장면.
  • 이것은 ___의 사이트입니다: 기술이 아닌 경험으로 채워집니다.
  • 시그니처 움직임: 이 사이트에만 존재하는 하나의 상호작용으로, 페이지에 코딩됩니다. 새로운 숫자가 있는 키트 장치는 해당되지 않습니다.
  • 의도적인 정지 구간을 표시하여 검사에서 죽은 스크롤과 구분할 수 있게 합니다.

1단계: 구조, 로그, 점수 매기기

이 순서대로 세 가지를 수행합니다. 코드 작성 전에 모두 완료해야 합니다.

참조/structures.md에서 구조를 선택합니다: 하나의 세계, 챕터, 제품 무대, 전시, 놀이터, 삽입이 있는 사설, 방송. 탐색, 시작 및 종료는 이에 따라 결정됩니다. BRIEF.md에 왜 다른 구조가 아닌 이것을 선택했는지 기록합니다.

지문 로그를 실행합니다. 빌드를 저장하는 폴더에서 FINGERPRINTS.md를 읽습니다(없으면 생성하며, 처음에는 비어 있습니다). 계획은 기존의 모든 행과 구조, 탐색, 히어로 장치, 장면 순서, 종료, 시그니처 움직임 중 최소 네 가지에서 달라야 합니다. 실패하면 로그가 아닌 계획을 변경합니다.

점수를 매깁니다. 먼저 느낌 곡선, 그 다음 비트당 장치를 BRIEF.md의 표로 작성합니다:

비트장면느낌장치스팬이 장치를 선택한 이유
인식히어로호기심유리 오브젝트 + 돌리2한 마디 읽기 전에 살아있는 제품
전환변형기대파티클 변형3노이즈가 형태가 되고 이름이 됨
정점레일경외카메라 레일3.5그 속을 여행하면 많은 것이 있음을 알게 됨
증명분해신뢰분해도2.5부품을 보여주며, 그것이 주장임
몰입종료평온평온 유지1.5페이지가 멈추고 클릭을 기다림

빌드 전 확인사항:

  • 선택한 구조의 금지 사항이 유지되는가.
  • 참조/scene-kit.md에서 네 개 이상의 장치 패밀리, 연속으로 두 번 사용 금지.
  • 인접한 두 장면의 느낌이 같지 않은가.
  • 정점이 확실히 가장 큰 스팬을 가지며, 그 앞의 장면은 더 조용한가.
  • 종료는 푸터로 사라지지 않고 해소되며 유지되는가.
  • 스팬은 화면 높이 단위입니다. 영화 같은 페이지는 8~14, 사설 및 놀이터 페이지는 더 짧을 수 있습니다. 숫자에 맞추기 위해 늘리지 마세요.

2단계: 빌드

mkdir -p <build> && cp <skill>/engine/stage.js <skill>/engine/stage.css <build>/

구조(import map, 캔버스, 섹션, 하나의 모듈 스크립트)는 templates/starter/index.html에서 시작하고, 점수를 매긴 장면 패턴을 차용합니다. 스타터나 Orbis 복사본을 배포하지 마세요. 모든 페이지는 자체 브리프를 기반으로 작성됩니다.

엔진 작동 방식(engine/stage.js, 헤더 주석 읽기):

  • 페이지는 <section data-act="name" data-span="2"> 스택입니다. 각 섹션은 섹션 길이 동안 고정되는 .frame을 포함합니다.
  • stage.act(name, { scene, camera, update(p, s), render(renderer, s), resize(w, h) })는 장면을 등록합니다. p는 장면 전체에서 0에서 1로 실행됩니다. s는 time, dt, pointer(부드러워짐, -1~1), velocity(스크롤 속도), width, height, reduced, coarse를 전달합니다.
  • 화면 중앙을 차지하는 장면이 렌더링됩니다. 하나의 scene 객체를 공유하는 장면들은 모두 함께 업데이트되므로, 단일 연속 세계는 여러 장면이 동일한 장면을 가리키는 것입니다.
  • p가 움직이려면 장면의 스팬이 1보다 커야 합니다. p는 프레임이 고정된 거리에서 측정되므로, 스팬이 정확히 1이면 p가 0에서 1로 바로 이동하며 그에 연결된 모든 것이 표시되지 않습니다. 1.25 이상을 사용하세요.
  • 모든 섹션은 CSS 변수 --p를 가지므로, 제목이 3D와 동일한 타임라인에서 움직일 수 있습니다.
  • 요소의 data-reveal은 진입 시 페이드 인합니다. style="--i:2"로 지연을 추가할 수 있습니다.
  • 하나의 장면을 비트로 나누려면 seg(p, a, b)를 사용하고, ease.inOut 등으로 모양을 만듭니다.
  • WebGL 없음: html.no-webgl은 각 장면의 .poster를 표시합니다. 모든 장면에 포스터(이미지 또는 그라데이션)를 제공하세요.

stage.css 상단의 토큰(캔버스, 표면, 잉크, 부드러운 잉크, 강조색, 강조 잉크, 두 개의 글꼴)으로 테마를 지정합니다. 하나의 프로젝트를 위해 엔진을 편집하지 마세요. 특별한 동작은 페이지 자체 스크립트에 작성합니다.

Three.js는 import map(jsdelivr의 [email protected])에 고정된 CDN 버전에서 제공됩니다. 고정을 유지하세요. 최신 버전이 필요한 경우, 최소 2주 이상 된 버전을 선택하고 검사를 다시 실행하세요.

마크업을 작성하기 전에 참조/design.md를 읽고, 두 번째 장면을 추가하기 전에 참조/performance.md를 읽으세요.

3단계: 증명

cd <build> && npm i playwright-core          # 빌드 폴더당 한 번; Google Chrome이 설치되어 있어야 함
node <skill>/scripts/serve.mjs --root . --port 4600 &
node <skill>/scripts/shoot.mjs --url http://localhost:4600 --out shots/desktop
node <skill>/scripts/shoot.mjs --url http://localhost:4600 --out shots/phone --width 390 --height 844 --touch
node <skill>/scripts/shoot.mjs --url http://localhost:4600 --out shots/reduced --reduced-motion --positions 0,1

스크립트는 각 장면을 다섯 위치로 스크롤하고, 부드러워짐이 안정될 때까지 기다린 후 각각 스크린샷을 찍고 sheet.png를 작성합니다. 페이지 오류, 실패한 요청, WebGL 없음, 아무것도 그리지 않는 장면, 가로 스크롤이 있으면 실패합니다. 통과는 실행된다는 의미일 뿐, 좋다는 의미는 아닙니다.

그런 다음 각 sheet.png를 열고 확인합니다. 각 위치의 각 장면에서: 모든 줄을 읽을 수 있습니까? 장면이 비트가 말하는 것을 보여줍니까? 휴대폰에서 잘리거나, 가려지거나, 너무 작은 부분이 있습니까? 정점이 정점처럼 보입니까? 종료가 해소됩니까? 수정하고, 다시 촬영하고, 다시 확인합니다.

그런 다음 느낌 확인 (참조/feel.md): 차갑게 스크롤하고, 각 장면에서 느낀 한 단어를 기록한 후 BRIEF.md의 곡선과 비교합니다. 불일치하는 부분이 있으면 페이지를 수정합니다.

확인되지 않은 사항을 솔직하게 말합니다: 헤드리스 Chrome은 WebGL을 소프트웨어로 렌더링하므로 보고하는 프레임 속도는 실제 기기의 것이 아니며, 실제 휴대폰에서의 스크롤 느낌을 알려줄 수 없습니다. 완료되었다고 말하기 전에 사용자에게 휴대폰에서 열어보도록 요청하세요.

엄격한 규칙

절대 금지대신
페이지 전체에 하나의 장면 장치네 개 이상의 패밀리, 연속으로 두 번 사용 금지
텍스처나 이미지에 구워진 텍스트캔버스 위의 실제 HTML
스크롤 화살표, 마우스 아이콘 또는 "스크롤하여 탐색"아무것도 없음. 히어로만으로 충분함
01 / 05와 같은 섹션 카운터삭제
모든 장면에서 중앙 정렬된 카피다양화: 왼쪽, 오른쪽, 중앙, 분할, 상단, 하단
대비를 위한 전체 화면 어두운 오버레이텍스트 블록 뒤에만 .scrim
그라데이션 텍스트, 네온 글로우두께와 크기로 강조
가상의 숫자나 통계사용자의 실제 수치만
보이는 카피의 대시마침표, 쉼표, 콜론
멈추지 않고 계속 회전하는 것움직임은 스크롤 또는 포인터를 따름; 유휴 움직임은 느리고 작게
섹션마다 새로운 WebGL 렌더러하나의 캔버스, 하나의 렌더러, 여러 장면(엔진이 처리)
스타터 페이지 배포페이지를 자체 브리프에서 작성
구조, 로그, 점수 매기기 전에 빌드1단계, 세 가지 모두
두 개의 정점 또는 없음하나, 가장 많은 공간과 그 앞에 조용한 장면
세 개 이상의 로그 열에서 이전 빌드와 일치하는 계획로그가 아닌 계획 변경
3단계 없이 완료되었다고 말하기3단계 실행, 시트 확인, 느낌 확인

출력

빌드 폴더, 그 다음 짧은 보고서: 구조와 그 이유, 각 행에 대한 지문 결과, 여정, 느낌 곡선과 정점, 점수 표, 시그니처 움직임, 세 번의 실행에서 shoot.mjs가 보고한 내용, 시트에서 확인하고 수정한 사항, 느낌 확인(의도한 것과 실제 느낀 것), 그리고 확인할 수 없었던 사항. 로컬 URL을 제공합니다. 그런 다음 FINGERPRINTS.md에 빌드 행을 추가합니다.

관련 스킬