| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- gemini 4.0
- GitHub Pages 배포
- Anthropic
- AI스토리북
- githubPages
- #GoogleAIStudio
- 고고천문학
- TypeScript
- 포켓 월드
- argon
- GPT-6
- ChatGPT
- ai모델비교
- Gemini/Managed Agent
- ManagedAgent
- GEMINI
- desk racer
- 아르곤 테니스
- webgl
- 회계 장부 인터랙티브 대시보드
- AI 코딩
- 차코캐니언
- openai
- threejs
- 재무 데이터 시각화
- ai studio
- 자연어 질의
- react
- cozy plow
- Google AI Studio
- Today
- Total
AI 로 실현하는 디지털 생활의 즐거움. DiJoy AI
[WebGL2/Three.js] Google AI Studio로 개발한 실시간 3D GPU 털(Fur) 시뮬레이션 & 물리 엔진 개발기 (ft. GitHub Pages 배포) 본문
[WebGL2/Three.js] Google AI Studio로 개발한 실시간 3D GPU 털(Fur) 시뮬레이션 & 물리 엔진 개발기 (ft. GitHub Pages 배포)
dijoy 2026. 10. 16. 17:37
요약: Google AI Studio와 Three.js, WebGL2/GLSL 커스텀 셰이더를 활용하여 64층 볼륨 쉘(Volumetric Shells)과 60,000가닥의 인스턴스 헤어 스트랜드, GPGPU 베를레(Verlet) 물리 시뮬레이션, Marschner 헤어 셰이딩, 실시간 AR 웹캠 조명 추정까지 구현한 풀스택 3D 그래픽스 프로젝트 개발기입니다.
📌 목차
- 프로젝트 소개: Mochi-Puff 3D GPU 털 시뮬레이션
- 왜 3D 웹 털(Fur) 시뮬레이션인가? 기술적 도전 과제
- Google AI Studio를 활용한 개발 여정 & 프롬프트 엔지니어링 노하우
- 핵심 그래픽스 및 물리 아키텍처
- 4.1 64층 볼류메트릭 쉘 & 60,000가닥 인스턴스 스트랜드 하이브리드
- 4.2 GPGPU 핑퐁 렌더타깃 기반 베를레(Verlet) 물리 엔진
- 4.3 Marschner 듀얼 엽(Lobe) 물리 기반 헤어 셰이딩
- 4.4 마우스/터치 인터랙션: 쓰다듬기(Petting), 빗질(Combing), 콕 찌르기(Boop 충격파)
- 4.5 실시간 AR 웹캠 모드 & 동적 조명 추정(켈빈 색온도 & 방향 검출)
- 4.6 360° 절차적 환경 시스템 (스튜디오, 구름 바다 하늘, 틸트시프트 데스크)
- 핵심 소스 코드 분석 (GLSL & Three.js)
- 모바일 & 데스크톱 60 FPS 방어를 위한 최적화 (Zero-GC)
- GitHub 배포 및 GitHub Pages 실시간 체험 링크
- 마치며: AI Studio와 웹 그래픽스의 미래
1. 프로젝트 소개: Mochi-Puff 3D GPU 털 시뮬레이션
웹 브라우저에서 고품질의 털(Fur/Hair)을 실시간으로 렌더링하고, 사용자의 손짓이나 마우스에 반응해 흔들리는 물리 효과를 구현하는 것은 오랫동안 고성능 콘솔이나 데스크톱 게임 엔진(Unreal, Unity)의 전유물로 여겨져 왔습니다.
이번에 개발한 "Mochi-Puff (모찌-퍼프)"는 웹 브라우저만으로 동작하는 순수 WebGL2 / Three.js 기반의 초현실적 인터랙티브 3D 털 시뮬레이션 프로젝트입니다.
🌟 주요 특징 요약
- 하이브리드 털 렌더링: 64단계 정밀 볼류메트릭 쉘(Volumetric Shells) 확장 + 60,000가닥의 3D 인스턴스 헤어 스트랜드 동시 렌더링.
- GPGPU 물리 시뮬레이션: CPU 부담 없이 GPU 텍스처 핑퐁(Ping-Pong)을 통한 베를레(Verlet) 적분 물리, 탄성, 감쇠, 바람(Wind) 효과 계산.
- Marschner 헤어 셰이딩 모델: 모근(Root)에서 끝단(Tip)으로의 색상 그라데이션, 큐티클 각도에 따른 주 하이라이트(R) 및 내부 반사 보조 하이라이트(TRT), 투과광(TT) 림 스캐터링.
- 실시간 인터랙티브 조작: 마우스 드래그를 통한 빗질(Combing), 쓰다듬기(Petting), 클릭 시 몸 전체로 전파되는 탄성 충격파(Boop Shockwave).
- 실시간 AR 카메라 환경: 웹캠 비디오 프레임을 실시간 파싱하여 실제 주변 조명의 색온도(Kelvin), 광원 방향, 조도를 자동 추정하여 3D 조명에 실시간 투영.
- 다국어 지원 (Bilingual): 기본 한국어(한글) 탑재 및 영문 실시간 전환 지원.
2. 왜 3D 웹 털(Fur) 시뮬레이션인가? 기술적 도전 과제
웹에서 털을 사실적으로 렌더링하려면 몇 가지 거대한 장벽이 존재합니다:
- 지오메트리 복잡도: 수만~수십만 가닥의 헤어 폴리곤을 CPU에서 매 프레임 변형(Deform)하면 초당 5프레임도 나오기 어렵습니다.
- 반투명 블렌딩과 Overdraw: 털의 투명도(Alpha)를 처리하면서 발생하는 깊이 정렬(Depth Sorting) 문제와 모바일 GPU의 필레이트(Fill-rate) 병목 현상.
- 가비지 컬렉션(GC) 스터터링: 물리 계산이나 애니메이션 과정에서 매 프레임
new THREE.Vector3()같은 객체를 생성하면 브라우저 가비지 컬렉터가 주기적으로 실행되어 화면이 뚝뚝 끊기는 현상.
이 세 가지 한계를 극복하기 위해 본 프로젝트에서는 GPU 파이프라인 중심의 설계(GPGPU + Instanced Shading + Zero-GC)를 채택했습니다.
3. Google AI Studio를 활용한 개발 여정 & 프롬프트 엔지니어링 노하우
이 복잡한 프로젝트를 밑바닥부터 구현하고 고도화하는 과정에서 Google AI Studio(Gemini 1.5 Pro / Flash)는 최고의 시니어 그래픽스 엔지니어 파트너 역할을 해주었습니다.
💡 AI Studio 활용 팁 & 성공 프롬프트 구조
수학적/물리학적 요구사항을 명확히 명시하기:
단순히 "털이 예쁘게 흔들리게 해줘"라고 요청하는 대신, 다음과 같이 물리학 원리를 프롬프트에 직접 녹여냈습니다:*"Three.js에서 털 시뮬레이션을 구현하려고 해. 64개 층의 볼류메트릭 쉘 기법을 사용하되, 버텍스 셰이더에서 법선 벡터 방향으로 정점을 밀어내고, GPGPU FBO 텍스처로부터 변위(Displacement) 벡터를 읽어 베를레(Verlet) 적분 기반의 관성과 2계 스프링-댐퍼 시스템을 적용해줘. Marschner 헤어 모델의 R(직접 반사)과 TRT(내부 굴절 반사) 듀얼 하이라이트 공식을 GLSL 프래그먼트 셰이더로 작성해줘."*
반복적(Iterative) 코드 리팩토링 & 벤치마킹:
처음에는 CPU에서 연산하던 물리 좌표를 AI Studio에 요청하여 GPGPU Ping-Pong 렌더 타깃 셰이더로 이전시켰습니다. AI Studio는 WebGL2 텍스처 포맷(RGBA32F또는HALF_FLOAT)의 부동소수점 호환성 문제와 iOS 사파리에서의 OES_texture_float 제약까지 사전에 고려한 안전한 폴백(Fallback) 코드를 작성해주었습니다.UI/UX 글래스모피즘과 다국어 지원:
3D 뷰포트를 가리지 않는 미니멀한 글래스모피즘(Glassmorphic) UI와 직관적인 인터랙션, 모바일 하단 시트(Bottom Sheet) 제스처까지 완벽하게 분리된 모듈형 아키텍처로 설계할 수 있었습니다.
4. 핵심 그래픽스 및 물리 아키텍처
+--------------------------------------------------------------------------+
| Mochi-Puff Engine |
+--------------------------------------------------------------------------+
| |
v v
[ 64 Volumetric Shells ] [ GPGPU Verlet Physics ]
- Vertex Extrusion along Normals - Ping-Pong Framebuffers (FBO)
- Procedural Noise Curl & Clumping - Wind & Drag Force Injection
- Marschner Dual-Lobe Shading - Pointer Combing & Petting
- Under-skin Occlusion - Boop Shockwave Propagation
| |
+----------------------+-----------------------+
|
v
[ Hybrid Composite Render ]
|
v
[ Real-Time Environments & Lighting Rig ]
- Studio (Black Cyclorama & 3-Point Rig)
- Cloud Sea (Procedural 360 Sky + Lens Flare)
- Cozy Desk (Tilt-Shift Bokeh + Walnut Table)
- AR Camera (Webcam Kelvin + Light Direction)4.1 64층 볼류메트릭 쉘 & 60,000가닥 인스턴스 스트랜드
털의 밀도감과 부드러운 음영을 위해 볼류메트릭 쉘(Volumetric Shells) 기법을 사용합니다.
- 기본 메시를 법선(Normal) 방향으로 미세하게 64회 확장하여 렌더링합니다.
- 외부 층으로 갈수록 노이즈 함수를 사용해 알파 값을 알파 투과율 곡선에 맞춰 깎아냄으로써 개별 털 가닥의 뭉침(Clumping)과 컬(Curl)을 표현합니다.
- 동시에 60,000개의 InstancedMesh 스트랜드를 오버레이하여 바람에 나부끼는 끝단 가닥의 실체감을 극대화했습니다.
4.2 GPGPU 핑퐁 렌더타깃 기반 베를레(Verlet) 물리
CPU에서 60,000개 이상의 정점을 연산하면 모바일 기기는 발열과 프레임 드랍을 겪습니다. 이를 해결하기 위해 두 개의 렌더타깃(FBO)을 번갈아 읽고 쓰는 핑퐁(Ping-Pong) GPGPU 파이프라인을 구축했습니다.
- 현재 위치 텍스처와 이전 위치 텍스처의 차이를 통해 속도(Velocity)를 암시적으로 계산.
- 외력(중력, 바람 벡터, 사용자의 마우스/터치 드래그 벡터, Boop 탄성 충격파)을 픽셀 셰이더에서 일괄 가산.
- 변위된 텍셀 데이터가 쉘 버텍스 셰이더로 바로 전달되어 지연 시간 없는 즉각적인 피동 모션을 완성합니다.
4.3 Marschner 듀얼 엽(Lobe) 물리 기반 헤어 셰이딩
일반 퐁(Phong)이나 블린-퐁(Blinn-Phong) 셰이딩은 플라스틱 같은 질감을 줍니다. 실제 포유류의 털과 머리카락은 원통형 섬유 표면의 미세한 비늘(Cuticle Scale)로 인해 빛이 굴절 및 내부 반사됩니다:
- R Lobe (직접 반사): 큐티클의 경사각(-3°~-5°)으로 인해 하이라이트가 빛의 입사각보다 살짝 어긋나 맺히는 밝은 하이라이트.
- TRT Lobe (내부 반사): 빛이 털 속으로 들어갔다가 반대편 내벽에서 2차 반사되어 나오는 색조 띤 보조 하이라이트.
- TT Lobe (투과 림 스캐터): 역광 상태에서 털의 윤곽선이 금빛이나 푸른빛으로 보송보송하게 빛나는 후방 산란(Back-scattering).
4.4 마우스/터치 인터랙션: Petting, Combing, Boop Shockwave
- 화면에서 모찌-퍼프 위를 드래그하면 광선 투사(Raycasting)를 통해 표면 국소 좌표계 상의 접선 속도를 계산하고, 이를 털의 빗질(Combing) 방향으로 영구/반영구적 변형을 인가합니다.
- 모찌의 볼이나 코를 클릭하면 Boop Shockwave가 발생하여 구형 감쇠 파동이 털 표면 전체를 흔들며 젤리처럼 탱글탱글하게 튕겨 나옵니다.
4.5 실시간 AR 웹캠 모드 & 동적 조명 추정
증강현실(AR) 뷰를 활성화하면 웹캠 비디오 피드가 배경으로 투사되며:
- 프레임의 RGB 분포를 실시간으로 다운샘플링하여 평균 조도와 색온도(Kelvin: 2500K~8000K)를 자동 측정합니다.
- 비디오 내 밝기 경사도(Luminance Gradient)를 해석해 실제 방 안의 주 광원 위치(Key Light Vector)를 역추적합니다.
- 이를 3D 씬의 Directional Light 및 림 라이트 셰이더 유니폼에 실시간 주입하여, 마치 가상의 크리처가 실제 내 책상 위에 앉아 있는 것과 같은 사실적인 조명 통합을 이뤄냅니다.
5. 핵심 소스 코드 분석 (GLSL & Three.js)
💻 1. 볼류메트릭 쉘 버텍스 셰이더 (변위 및 물리 인가)
// furShaders.js - 버텍스 셰이더 발췌
uniform float uFurLength;
uniform float uLayerIndex; // 0.0 ~ 1.0 (현재 쉘 층의 높이 비율)
uniform sampler2D uPhysicsTex; // GPGPU 물리 변위 텍스처
uniform vec3 uPointerLocalPos;
uniform float uBoopShockwave;
varying vec3 vWorldNormal;
varying vec2 vUv;
varying float vLayer;
void main() {
vUv = uv;
vLayer = uLayerIndex;
// GPGPU 물리 텍스처로부터 실시간 변위(Displacement) 벡터 샘플링
vec3 physicsDisp = texture2D(uPhysicsTex, uv).xyz;
// 외곽 층으로 갈수록 변위 효과와 중력 처짐이 강해짐 (layer^1.6)
float layerFactor = pow(uLayerIndex, 1.6);
// Boop 탄성 충격파: 중심점으로부터 구면 파동 전파
float distToBoop = length(position - uPointerLocalPos);
float boopWave = sin(distToBoop * 14.0 - uLayerIndex * 6.28) * exp(-distToBoop * 2.5);
vec3 boopOffset = normal * (boopWave * uBoopShockwave * 0.18);
// 법선 방향 확장 + 물리 변위 + 충격파 결합
vec3 displacedPos = position + (normal * uFurLength * uLayerIndex);
displacedPos += (physicsDisp * layerFactor * 0.42);
displacedPos += boopOffset;
vWorldNormal = normalize(mat3(modelMatrix) * normal);
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(displacedPos, 1.0);
}
💻 2. Marschner 스타일 듀얼 하이라이트 프래그먼트 셰이더
// furShaders.js - 프래그먼트 셰이더 발췌
uniform vec3 uBaseColor;
uniform vec3 uTipColor;
uniform vec3 uKeyLightDir;
uniform vec3 uKeyLightColor;
uniform float uRoughness;
uniform float uSpecular;
uniform float uRimIntensity;
varying vec3 vWorldNormal;
varying float vLayer;
void main() {
vec3 N = normalize(vWorldNormal);
vec3 L = normalize(uKeyLightDir);
vec3 V = normalize(cameraPosition - vWorldPosition);
vec3 H = normalize(L + V);
// 1. 모근 -> 모초 그라데이션 및 앰비언트 오클루전(AO)
float ao = pow(vLayer, 0.65); // 안쪽 층일수록 그림자 어둡게
vec3 furAlbedo = mix(uBaseColor, uTipColor, smoothstep(0.15, 0.85, vLayer));
// 2. Kajiya-Kay / Marschner R-Lobe (주 표면 반사)
float NdotH = max(0.0, dot(N, H));
float primarySpec = pow(NdotH, mix(32.0, 128.0, 1.0 - uRoughness)) * uSpecular;
// 3. Marschner TRT-Lobe (내부 굴절 및 채도 있는 보조 반사)
vec3 shiftedH = normalize(H + N * 0.12); // 큐티클 틸트 오프셋
float secondarySpec = pow(max(0.0, dot(N, shiftedH)), 24.0) * (uSpecular * 0.45);
vec3 trtColor = mix(furAlbedo, vec3(1.0), 0.3) * secondarySpec;
// 4. 역광 림 스캐터링 (TT Lobe)
float VdotL = dot(-V, L);
float rimScatter = pow(max(0.0, 1.0 - dot(N, V)), 2.8) * max(0.0, VdotL + 0.3);
vec3 rimLight = vec3(1.0, 0.95, 0.85) * (rimScatter * uRimIntensity * vLayer);
// 최종 조명 합성
float diff = max(0.15, dot(N, L));
vec3 finalColor = furAlbedo * (diff * uKeyLightColor + 0.25) * ao;
finalColor += uKeyLightColor * primarySpec * ao;
finalColor += trtColor * ao;
finalColor += rimLight;
// 절차적 알파 마스킹으로 털 가닥 끝단 뭉침 분리
float alphaMask = calculateFurAlpha(vUv, vLayer);
if (alphaMask < 0.05) discard;
gl_FragColor = vec4(finalColor, alphaMask);
}
6. 모바일 & 데스크톱 60 FPS 방어를 위한 최적화 (Zero-GC)
실시간 그래픽스 웹 앱에서 가장 흔한 버벅임의 원인은 가비지 컬렉션(GC)입니다.
- 미리 할당된 벡터 재사용 (Zero Garbage Collection):
animate()루프 내부에서new THREE.Vector3()나new THREE.Color()같은 인스턴스를 단 한 번도 생성하지 않습니다. 파일 상단에 임시 객체(tmpVecA,tmpVecB)를 정적으로 선언하고.copy(),.set(),.addScaledVector()메소드만 호출하여 메모리 할당량을 0 바이트로 유지합니다. - 동적 DPR 스로틀링 (Dynamic Pixel Ratio Guard):
아이폰이나 레티나 디스플레이에서 해상도가 3x를 초과할 경우 불필요한 과열이 일어납니다. 본 프로젝트는 최대 DPR을 2.0으로 캡(Cap)하고, 화면 녹화 모드나 프레임 저하 감지 시 즉시 1.0x로 자동 조율하는 안전 가드를 내장했습니다. - WebGL Fallback 모드 탑재:
구형 브라우저나 부동소수점 텍스처를 지원하지 않는 제한된 환경에서는 1클릭으로 GPGPU 연산을 비활성화하고, 초경량 해석적 스프링 댐퍼 물리 모드로 즉각 전환할 수 있습니다.
7. GitHub 배포 및 GitHub Pages 실시간 체험 링크
본 프로젝트의 전체 소스 코드는 GitHub에 공개되어 있으며, GitHub Pages를 통해 브라우저에서 바로 실시간 3D 털을 쓰다듬어 보실 수 있습니다.
🔗 GitHub 저장소 (Source Code):
https://github.com/djai32521/3D_GPU_Fur_Simulation🌐 GitHub Pages 실시간 데모 (Live Demo):
https://djai32521.github.io/3D_GPU_Fur_Simulation/
🎮 인터랙션 조작법
| 조작 | 기능 설명 |
|---|---|
| 마우스 드래그 / 터치 드래그 | 모찌-퍼프의 털을 실시간으로 쓰다듬고 빗질(Combing) |
| 몸체 클릭 / 탭 (Boop) | 모찌를 콕 찌르면 몸 전체로 전파되는 탄성 젤리 충격파 |
| 여백 드래그 | 카메라 360° 궤도 회전(Orbit) |
| 상단 바 언어 버튼 [한글/EN] | 한국어(기본)와 영어 간 즉각 번역 전환 |
| 우측 컨트롤 패널 | 사쿠라 모찌, 골든 플러프, 말차 퍼프 등 프리셋 및 털 길이/밀도/컬 조절 |
| AR 카메라 모드 | 웹캠을 켜서 방 안 실제 조명과 바닥 위에 모찌 배치하기 |
8. 마치며: AI Studio와 웹 그래픽스의 미래
Three.js와 커스텀 GLSL 셰이더, GPGPU 연산 파이프라인은 복잡한 선형대수학과 그래픽스 파이프라인 지식을 요구합니다.
이 프로젝트를 진행하면서 Google AI Studio는 단순히 코드를 대신 작성해주는 보조 도구를 넘어, 다음과 같은 그래픽스 엔지니어링의 핵심 병목을 해결하는 데 결정적인 역할을 했습니다:
- 복잡한 물리 수식의 실시간 셰이더 변환: 베를레 적분, Marschner 복합 반사 엽, 구면 파동 전파 수식을 GLSL 코드로 즉각 번역.
- 크로스 브라우징 및 엣지 케이스 디버깅: 모바일 사파리와 안드로이드 크롬 간의 렌더타깃 포맷 차이, 텍스처 필터링 이슈를 사전에 방지.
- 사용자 경험을 고려한 반응형 아키텍처 제안: 모바일 제스처와 글래스모피즘 UI, 완벽한 다국어 현지화까지 신속한 완결.
웹 브라우저의 성능과 WebGL/WebGPU의 발전 속도는 상상 이상으로 빠릅니다. 이제 설치 없이 브라우저 URL 접속만으로도 콘솔급 그래픽스 인터랙션을 누구나 즐길 수 있는 시대가 되었습니다.
궁금한 점이나 추가하고 싶은 기능 아이디어가 있다면 댓글이나 GitHub Issue/PR로 언제든 편하게 남겨주세요! 감사합니다.