three-expert
SKILL.md
Three.js/R3F 전문가
$ARGUMENTS Three.js 관련 질문에 답변하고 구현을 도와드립니다.
@pf-dev/three 패키지 구조
packages/three/src/
├── components/
│ ├── Canvas.tsx # R3F Canvas 래퍼
│ ├── SceneLighting.tsx # 조명 설정
│ ├── SceneGrid.tsx # 그리드 헬퍼
│ ├── Stats.tsx # 성능 통계
│ ├── GLTFModel.tsx # GLTF 로더
│ └── FBXModel.tsx # FBX 로더
├── stores/
│ ├── useFacilityStore.ts # 시설물 상태
│ ├── useAssetStore.ts # 에셋 상태
│ └── useFeatureStore.ts # Feature 상태
├── hooks/
│ ├── useModel.ts # 모델 로딩
│ └── useInteraction.ts # 인터랙션
└── utils/
└── instancing.ts # GPU Instancing
주요 패턴
기본 씬 설정
import { Canvas, SceneLighting, SceneGrid, Stats } from "@pf-dev/three";
function Scene() {
return (
<Canvas camera={{ position: [10, 10, 10], fov: 50 }} shadows>
<SceneLighting />
<SceneGrid size={100} />
<Stats />
{/* 3D 오브젝트들 */}
<MyModel />
</Canvas>
);
}
GLTF 모델 로딩
import { GLTFModel } from "@pf-dev/three";
function Building() {
return (
<GLTFModel
url="/models/building.glb"
position={[0, 0, 0]}
scale={1}
onLoad={(gltf) => {
console.log("Model loaded:", gltf);
}}
onClick={(event) => {
console.log("Clicked:", event.object.name);
}}
/>
);
}
인터랙션 (Hover, Select)
import { useInteraction } from "@pf-dev/three";
function InteractiveModel({ url }) {
const { hovered, selected, bind } = useInteraction();
return (
<GLTFModel
url={url}
{...bind()}
onPointerOver={() => console.log("hover")}
onPointerOut={() => console.log("out")}
onClick={() => console.log("click")}
>
{hovered && <Outline color="yellow" />}
{selected && <Outline color="blue" />}
</GLTFModel>
);
}
GPU Instancing (대량 오브젝트)
import { useMemo } from "react";
import { InstancedMesh } from "three";
function Trees({ positions }: { positions: [number, number, number][] }) {
const mesh = useMemo(() => {
const temp = new THREE.Object3D();
return positions.map((pos, i) => {
temp.position.set(...pos);
temp.updateMatrix();
return temp.matrix.clone();
});
}, [positions]);
return (
<instancedMesh args={[undefined, undefined, positions.length]}>
<cylinderGeometry args={[0.5, 0.5, 3]} />
<meshStandardMaterial color="brown" />
{mesh.map((matrix, i) => (
<primitive key={i} object={matrix} attach={`instanceMatrix-${i}`} />
))}
</instancedMesh>
);
}
// 또는 @pf-dev/three의 유틸리티 사용
import { createInstances } from "@pf-dev/three";
const instances = createInstances(geometry, material, transforms);
자주 묻는 질문
Q: 성능이 느려요
A: 최적화 방법
- GPU Instancing 사용 (동일 오브젝트 100개 이상)
- LOD (Level of Detail) 설정
- Frustum Culling 확인
- 텍스처 압축 (KTX2)
- Draco 압축 모델 사용
<Canvas
gl={{
antialias: false, // 안티앨리어싱 끄기
powerPreference: "high-performance",
}}
frameloop="demand" // 필요할 때만 렌더
>
Q: 모델이 안 보여요
A: 체크리스트
- 경로 확인 (
/public폴더) - 스케일 확인 (너무 작거나 큼)
- 카메라 위치 확인
- 조명 확인
// 디버깅용 박스 추가
<mesh position={[0, 0, 0]}>
<boxGeometry args={[1, 1, 1]} />
<meshBasicMaterial color="red" wireframe />
</mesh>
Q: 클릭이 안 돼요
A: raycaster 설정
<Canvas
raycaster={{
params: {
Mesh: { threshold: 0.1 },
Line: { threshold: 0.1 },
Points: { threshold: 0.1 },
},
}}
>
Q: 그림자가 이상해요
A: 그림자 설정
<Canvas shadows>
<directionalLight
castShadow
shadow-mapSize={[2048, 2048]}
shadow-camera-far={50}
shadow-camera-left={-10}
shadow-camera-right={10}
shadow-camera-top={10}
shadow-camera-bottom={-10}
/>
<mesh receiveShadow castShadow>
{/* ... */}
</mesh>
</Canvas>
카메라 제어
import { OrbitControls, PerspectiveCamera } from "@react-three/drei";
function Scene() {
const cameraRef = useRef();
const flyTo = (position: [number, number, number]) => {
// GSAP 또는 spring 애니메이션
gsap.to(cameraRef.current.position, {
x: position[0],
y: position[1],
z: position[2],
duration: 2,
});
};
return (
<>
<PerspectiveCamera ref={cameraRef} makeDefault position={[10, 10, 10]} />
<OrbitControls enableDamping dampingFactor={0.05} minDistance={5} maxDistance={100} />
</>
);
}
애니메이션
import { useFrame } from "@react-three/fiber";
function RotatingBox() {
const meshRef = useRef<THREE.Mesh>(null);
useFrame((state, delta) => {
if (meshRef.current) {
meshRef.current.rotation.y += delta;
}
});
return (
<mesh ref={meshRef}>
<boxGeometry />
<meshStandardMaterial color="orange" />
</mesh>
);
}
Context7 참고
Three.js, React Three Fiber 최신 API가 필요하면 Context7로 조회하세요.
Weekly Installs
2
Repository
pluxity/pf-frontendFirst Seen
12 days ago
Security Audits
Installed on
opencode2
gemini-cli2
codebuddy2
github-copilot2
codex2
kimi-cli2