Awwwards 스타일 3D 웹사이트
당신은 Active Theory, Lusion, 14islands, Bonhomme, Resn, Studio Freight, Locomotive 및 Igloo Inc.의 계보를 잇는 스크롤 기반의 영화 같은 3D 웹 경험을 구축하고 있습니다. 미적 목표는 프리미엄, 느리고, 부드럽게 보간(lerp)되며, 광택이 있고, 분위기 있는 것입니다. 절대 갑작스럽거나, 지나치게 복잡하거나, 기본값을 사용하지 않습니다.
핵심 철학
코드를 다루기 전에 이것들을 읽어보세요. 이것들이 'Three.js 데모'와 'Awwwards 사이트 오브 더 데이'를 구분짓습니다.
- 미적 요소 > 지오메트리. 좋은 HDRI, ACESFilmic 톤 매핑, 블룸이 적용된 6각형 큐브가 단일 DirectionalLight로 비춰진 20만 폴리곤 모델보다 더 나아 보입니다. 예산은 지오메트리보다 조명/후처리에 먼저 투자하세요.
- 모든 것을 lerp하세요. 어떤 값도 즉시 변경되어서는 안 됩니다. 카메라 위치, 회전, 스크롤 진행 상황, 마우스 위치, 심지어 레이캐스터 대상까지도 모두 댐핑 계수(0.06–0.1이 적정 범위)를 통해 실행되어야 합니다. 아무것도 고정되지 않았기 때문에 세상이 살아있는 것처럼 느껴집니다.
- 가능하면 단일 HTML 파일로. 기본 결과물은
unpkg(및 GSAP용esm.sh)의 ESM 가져오기를 사용하는 하나의.html파일입니다. 사용자가 명시적으로 요청하지 않는 한 빌드 단계가 없습니다. 이렇게 하면 작업물을 이식 가능하고, 검토 가능하며, 공유 가능하게 만듭니다. - 모바일 우선, 성능 항상 최우선.
pixelRatio를Math.min(devicePixelRatio, 2)로 제한하세요. Frustum culling을 수행하세요. 모바일에서는 후처리를 절반으로 줄이세요. 완료했다고 선언하기 전에 Chrome DevTools에서 중간급 Android 기기로 테스트하세요. - ACESFilmic 톤 매핑은 타협할 수 없습니다.
renderer.toneMapping = THREE.ACESFilmicToneMapping및renderer.outputColorSpace = THREE.SRGBColorSpace를 사용하세요. 이것 없이는 모든 것이 평평하고 'WebGL스러워' 보입니다. metalness > 0에는 환경 맵이 필요합니다. envMap이 없는 금속 재질은 검은 덩어리입니다. 금속/유리를 도입하기 전에 항상 HDRI(또는 대체재로RoomEnvironment)를 로드하세요.- 데스크탑에서 60fps 목표, 모바일에서 30fps 최소. 이를 달성할 수 없다면 지오메트리를 줄이기 전에 후처리 패스를 줄이세요. 눈은 삼각형보다 노이즈를 더 민감하게 알아차립니다.
고정 기술 스택
이 버전들은 함께 테스트되었습니다. 물어보지 않고 업그레이드하지 마세요.
three 0.170.0
gsap 3.12.5 (ScrollTrigger 포함)
lenis 1.1.0 (@studio-freight/lenis 아님 — 해당 스코프는 폐기됨)
후처리는 **three/addons/postprocessing/의 three 내장 EffectComposer**를 사용합니다. 독립형 postprocessing 라이브러리(v6.36.0)는 이 스킬에서 평가 후 제외되었습니다. 해당 라이브러리의 내부는 Material.onBeforeRender()를 호출하는데, three r170에서 이 메서드가 제거되어 프레임당 머티리얼당 콘솔 경고가 발생합니다. Three 내장 패스(UnrealBloomPass, OutputPass, ShaderPass, LUTPass 등)는 버전 불일치 없이 필요한 모든 효과를 처리합니다.
유리는 transmission: 1.0 + dispersion: 1.2(r166+ 기능 — 외부 라이브러리 없이 색수차 굴절)와 함께 **three 내장 MeshPhysicalMaterial**을 사용합니다. drei-vanilla의 MeshTransmissionMaterial은 three 코어/애드온에 포함되어 있지 않습니다. 시간적 왜곡이나 객체별 백버퍼 샘플링이 필요한 경우에만 사용하세요(그런 다음 drei-vanilla 및 [email protected]을 importmap에 추가). 두 경로 모두 PATTERNS.md #5를 참조하세요.
CDN 가져오기는 다음 importmap 패턴을 사용합니다(표준 예제는 assets/templates/minimal.html 참조):
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/[email protected]/build/three.module.js",
"three/addons/": "https://unpkg.com/[email protected]/examples/jsm/",
"gsap": "https://esm.sh/[email protected]",
"gsap/ScrollTrigger": "https://esm.sh/[email protected]/ScrollTrigger",
"lenis": "https://unpkg.com/[email protected]/dist/lenis.mjs"
}
}
</script>
컴포저 선택 — 확정됨: 이 스킬은
three/addons/postprocessing/의 three 내장EffectComposer를 사용합니다. 독립형postprocessingnpm 라이브러리는 테스트 후 거부되었습니다:[email protected]은 r170에서 제거된Material.onBeforeRender()에 플래그를 지정하여 프레임당 머티리얼당 한 번씩 콘솔을 오염시킵니다. Three 내장 패스는 이 스킬에 필요한 모든 효과(블룸, ShaderPass를 통한 비네트, ShaderPass를 통한 그레인, LUTPass를 통한 LUT, OutputPass를 통한 출력 톤 매핑)를 처리합니다. 표준 패스 체인은references/POST_PROCESSING.md를 참조하세요.
CDN 안정성:
three및lenis의 경우 기본적으로unpkg.com을 사용하세요. npm 디렉토리 구조를 정확히 미러링하므로three/addons/...가 깔끔하게 해석됩니다.cdn.jsdelivr.net은 테스트했지만 일부 네트워크에서[email protected]/examples/jsm/postprocessing/*파일을 간헐적으로 제공하지 못했습니다(ERR_CONNECTION_CLOSED). GSAP의 경우esm.sh를 사용하는 것이 GSAP UMD 번들에 가장 깔끔한 ESM 게이트웨이이기 때문입니다. unpkg에 연결할 수 없는 경우 대체 순서: unpkg → esm.sh → cdn.skypack.dev입니다. 프로덕션의 경우 파일을 로컬로 가져오세요(/vendor/에 다운로드). 엄격한 CDN 의존성은 프로토타입에만 허용됩니다.
업데이트 정책: 버전은 함께 테스트되었기 때문에 고정되어 있습니다. 업그레이드하려면: (1) 먼저
assets/templates/minimal.html에서 버전을 올리고, (2) 브라우저에서 네 개의 템플릿을 모두 실행하고, (3) 발생한 모든 문제를 수정하고, (4) SKILL.md와 PATTERNS.md를 업데이트하세요. 단일 템플릿에서 조용히 버전을 올리지 마세요. 템플릿 간 버전 불일치는 '내 컴퓨터에서는 작동함' 문제의 주요 원인입니다.
5단계 워크플로우
이 순서를 따르세요. 단계를 건너뛰면 '프리미엄 사이트'가 아닌 '기술 데모' 결과물이 생성됩니다.
1단계 — 경험 아키타입 식별
모든 Awwwards 3D 사이트는 다음 중 하나에 속합니다. 하나를 선택하고 고정하세요:
| 아키타입 | 패턴 | 참고 자료 |
|---|---|---|
| 객체 쇼케이스 | 단일 히어로 객체, 스크롤 시 카메라 궤도/줌 | Bonhomme 제품 페이지, Apple AirPods Pro |
| 방 산책 | 3D 인테리어를 통한 카메라 경로 | Igloo Inc., Bruno Simon 포트폴리오 |
| 터널 | 끝없는 지오메트리를 통과하는 카메라 비행 | Active Theory 실험 |
| 수직 하강 | 스크롤 = 레이어를 통한 하강/상승 | 14islands 사례 연구 |
| 비행 | 풍경을 가로지르는 카메라 | Lusion 사례 연구 |
| 파티클 필드 | 스크롤/마우스에 반응하는 수천 개의 점 | Resn 실험 |
사용자가 말하지 않았다면 어떤 아키타입을 원하는지 물어보세요. 새로운 것을 발명하지 마세요. 이들은 검증된 것입니다.
2단계 — 에셋 계획
기준을 충족하는 가장 저렴한 소스를 선택하세요:
- Three.js 프리미티브 (
SphereGeometry,BoxGeometry,TorusKnotGeometry) — 추상/쇼케이스 작업용. 대부분의 Awwwards 사이트가 이것들을 사용합니다. 간과하지 마세요. - MCP를 통한 Blender — 사용자 정의 모양이 필요한 경우.
references/BLENDER_PIPELINE.md에서 레시피(동전, 유리 구체, 블롭, 저폴리 방) 및 GLB 내보내기 구성(Draco + KTX2)을 참조하세요. - Polyhaven — HDRI 및 텍스처, 무료, CC0. HDRI가 모델보다 더 중요합니다.
- Sketchfab — 기성 모델의 최후의 수단. 항상 폴리곤 수를 확인하세요.
3단계 — 템플릿 선택
assets/templates/에서 시작하세요:
minimal.html— HDRI, 톤 매핑, Lenis, 후처리가 연결된 빈 장면. 사용자 정의 작업의 기초로 사용하세요.coin-scroll.html— 동전이 스크롤에 따라 회전하고 떨어집니다(객체 쇼케이스).room-walkthrough.html— 카메라가 방을 통해 스플라인을 따라 이동합니다(방 산책).glass-product.html—MeshPhysicalMaterial전송 + 분산(r166+), HDRI, 부드러운 블룸이 있는 단일 제품(객체 쇼케이스, 유리).
템플릿은 시작점일 뿐 최종 작업물이 아닙니다. 필요 없는 것은 제거하고, 필요한 것은 레이어링하세요.
4단계 — 폴리시 레이어링 (이 순서대로)
순서가 중요합니다. 각 레이어는 이전 레이어가 제자리에 있다고 가정합니다.
- HDRI 로드되어
scene.environment으로 적용됨 - 톤 매핑 —
ACESFilmicToneMapping, 노출1.0–1.2 - 조명 — HDRI가 있어도 그림자 방향을 위해
DirectionalLight하나 추가 - 후처리 — three 내장
EffectComposer와 HDR 대상 →RenderPass→UnrealBloomPass(강도 ~0.45, 반경 0.4, 임계값 0.82) → 비네트ShaderPass→OutputPass(renderer.toneMapping = ACESFilmic적용) → 마지막으로 그레인ShaderPass - Lenis 부드러운 스크롤을 GSAP
ScrollTrigger.update에 연결 - 사용자 정의 커서 (선택 사항이지만 Bonhomme/Lusion의 특징)
- 스크롤 타임라인 —
ScrollTrigger로 구동되는 GSAP 타임라인, 카메라/객체 속성 lerp - 필름 그레인 최종 합성 레이어 — 시간 기반 노이즈 프래그먼트가 포함된 사용자 정의
ShaderPass, 강도 ~0.05 (references/POST_PROCESSING.md§ "패스 5 — 필름 그레인" 참조)
5단계 — 성능 감사
완료했다고 선언하기 전에:
- Lighthouse 성능 ≥ 데스크탑 85, 모바일 70
- FCP < 1.8초, LCP < 2.5초
- 데스크탑 60fps, 중급 Android에서 최소 30fps
-
pixelRatio2로 제한 - GLB 파일 Draco 압축, 가능한 경우 텍스처 KTX2
-
requestAnimationFrame루프 내부에console.log없음 (DevTools에서 성능 저하) - 모든 애니메이션은 프레임 수가 아닌
delta시간으로 구동됨
엄격한 규칙 — 절대 하지 말아야 할 것
이것들은 망가진 작업물을 만듭니다. 자세한 내용은 references/ANTI_PATTERNS.md를 참조하세요.
- 스냅 애니메이션 금지. 모든 속성 변경은 lerp 또는 GSAP
ease를 통해 이루어져야 합니다. - 환경 맵 없이
metalness > 0금지. 결과: 검은 덩어리. - 제한되지 않은
pixelRatio금지.devicePixelRatio = 2인 4K 모니터는 15fps로 떨어집니다. - 압축되지 않은 GLB 금지. Draco 압축은 필수입니다(
BLENDER_PIPELINE.md참조). - 자동 재생 오디오 금지. 브라우저가 차단하고 사용자가 싫어합니다.
- 애니메이션 루프에서
console.log금지. 프레임당 한 번만 있어도 DevTools를 망가뜨립니다. - CSS 기반 스크롤과 JS 기반 스크롤 혼합 금지. Lenis가 스크롤을 소유합니다. ScrollTrigger는 Lenis로부터 읽습니다. CSS
scroll-behavior: smooth는 제거되어야 합니다. - 프로덕션에서
OrbitControls금지. 프로토타이핑용입니다. 실제 사이트는 스크롤 기반 카메라를 사용합니다. - 정밀도 선언 없는
ShaderMaterial금지. 모바일 GPU에는precision mediump float;가 필요합니다. - 매 프레임 전체 장면에 대한 레이캐스팅 금지. 상호 작용 가능한 메시의 작은 배열로 필터링하세요.
- 프레임 수 기반 애니메이션 금지. 모든 모션은
clock.getDelta()의delta로 구동되고 곱해져야 합니다. 144Hz 모니터와 30Hz 모니터는 시각적으로 동일한 모션을 생성해야 합니다. lerp의 경우 프레임 속도 독립적인 공식을 사용하세요: 원시ease대신factor = 1 - Math.pow(1 - ease, delta * 60).
참고 파일
필요할 때만 로드하세요. 시작할 때 모두 읽지 마세요.
references/ARCHITECTURE.md— 장면 구조, lerp/스크롤 루프, 렌더 순서references/PATTERNS.md— 일반적인 요구 사항을 위한 33개의 복사-붙여넣기 코드 스니펫references/PROCEDURAL_GEOMETRY.md— 코드 전용 지오메트리 생성; 프리미티브, 수학 기반 모양, 정점 변위, 하이브리드 Blender 패턴. AI 3D 생성기에 도달하기 전의 기본 경로입니다.references/BLENDER_PIPELINE.md— Blender MCP 레시피 + GLB 내보내기 구성references/SHADERS.md— GLSL 빌딩 블록 (노이즈, 프레넬, 분산, 사용자 정의 재질)references/POST_PROCESSING.md— 블룸, 피사계 심도(DOF), 그레인, 색수차 레시피references/TRANSITIONS.md— Barba.js 페이지 전환, View Transitions APIreferences/ANTI_PATTERNS.md— 미학을 망치는 것들과 그 이유에 대한 긴 목록
영감 아카이브
사용자가 방향을 정하지 못할 때 여기를 가리키세요. 브라우저에서 열고, 스크린샷을 찍거나 스크랩하지 마세요.
- Active Theory — https://activetheory.net — WebGL 플레어, GLSL 왜곡, 수제 블룸 및 분산의 대가
- Lusion — https://lusion.co — 초현실적인 제품 쇼케이스, 투과성 재질, 완벽한 색상 그레이딩
- 14islands — https://14islands.com — 장난기 넘치는 3D, 독특한 페이지 전환, 장면 위의 세련된 타이포그래피
- Bonhomme — https://bonhomme.lol — 대담한 타이포그래피와 3D의 만남, 독특한 커서, 아트 디렉션 주도
- Resn — https://resn.co.nz — 분위기 있는 파티클 작업, 꿈같은 팔레트, 느린 카메라 움직임
- Studio Freight — https://studiofreight.com — Lenis의 저자; 미니멀리즘 + 완벽하게 조정된 부드러움
- Locomotive — https://locomotive.ca — 원래 Locomotive Scroll 저자; 스크롤 안무의 대가
- Igloo Inc. — https://igloo.inc — 풍경 비행, 내러티브 페이싱, Pixar 수준의 조명
- Awwwards 사이트 오브 더 데이 — https://www.awwwards.com/websites/sites_of_the_day/ — 최신 트렌드를 위한 일일 큐레이션 아카이브
오디오 (선택 사항이지만 특징적)
Awwwards 3D 수상작의 약 70%는 미묘한 오디오(앰비언트 드론, 호버 틱, 스크롤 우우시)를 포함합니다. 잘 사용하면 오디오는 '사이트'와 '경험'의 차이를 만듭니다. 잘못 사용하면 사용자가 처음 2초 안에 탭을 닫는 이유가 됩니다.
규칙:
- Howler.js (
https://esm.sh/[email protected]) 또는 Web Audio API를 사용하세요. 앰비언트에는<audio>태그를 사용하지 마세요. - 항상 사용자 제스처(버튼 클릭, 첫 뷰포트를 지난 스크롤) 뒤에 재생을 게이트하세요. 브라우저가 어차피 자동 재생을 차단하지만, UX 규칙은 더 엄격합니다: 사용자가 요청하지 않은 사운드를 절대 시작하지 마세요.
- UI 모서리에 지속적인 음소거 토글을 제공하세요. 기본값: 모바일에서 OFF, 첫 방문에서 OFF (
localStorage를 사용하여 사용자의 선택을 기억하세요). - 앰비언트를 -18 dB에서 -24 dB로 루프하세요. UI 사운드는 낮게 유지하세요.
프로젝트 구조
권장되는 최종 프로젝트 구조:
project/
├── index.html # 기본 결과물 (단일 파일 규칙 준수 시)
├── assets/
│ ├── models/ # .glb 파일 (Draco 압축)
│ ├── textures/ # .ktx2 또는 .webp 텍스처
│ ├── hdri/ # .hdr 또는 .exr 환경 맵
│ └── templates/ # 시작 템플릿 (minimal.html 등)
├── vendor/ # 프로덕션을 위한 로컬 라이브러리 사본
├── references/ # 이 스킬의 참고 문서
└── audio/ # 오디오 파일
참고:
- 단일 HTML 파일 규칙이 적용되는 경우 모든 에셋은 CDN 또는 인라인 데이터 URI에서 로드되어야 합니다.
- 빌드 단계가 필요한 경우 권장 도구는 Vite입니다 (
npm create vite@latest). 그러나 기본값은 빌드 단계 없음입니다. vendor/디렉토리는 프로덕션에만 해당되며 프로토타입에는 필요하지 않습니다.