# 3D Web
- [WebGL Overlay View를 사용한 3D 지도 환경 빌드](https://developers.google.com/codelabs/maps-platform/webgl?hl=ko#0)
- [웹사이트에 지도 추가하기(자바스크립트)](https://developers.google.com/codelabs/maps-platform/maps-platform-101-js?hl=ko#1)
- [Maps JavaScript API](https://developers.google.com/maps/documentation/javascript/?hl=ko)
- [마커 클러스터링](https://developers.google.com/maps/documentation/javascript/marker-clustering?hl=ko)
- [Tilt and Rotation](https://developers.google.com/maps/documentation/javascript/examples/webgl/webgl-tilt-rotation)
- [기울기 및 회전](https://developers.google.com/maps/documentation/javascript/webgl/tilt-rotation?hl=ko)
- [Ground Overlays](https://developers.google.com/maps/documentation/javascript/examples/groundoverlay-simple)
- [WebGL 오버레이 뷰](https://developers.google.com/maps/documentation/javascript/webgl/webgl-overlay-view?hl=ko)
# WebGL 오버레이 뷰 추가
setMap을 사용하여 지도 인스턴스에 전달
```javascript
// Create a map instance.
const map = new google.maps.Map(mapDiv, mapOptions);
// Create a WebGL Overlay View instance.
const webglOverlayView = new google.maps.WebGLOverlayView();
// Add the overlay to the map.
webglOverlayView.setMap(map);
```
# 수명주기
- onAdd()
- 오버레이가 생성될 때 호출
- 오버레이가 그려지기 전에 WebGL 렌더링 컨텍스트에 즉시 액세스할 필요가 없는 중간 데이터 구조를 가져오거나 만들 수 있다.
- onContextRestored({gl})
- 렌더링 컨텍스트를 사용할 수 있는 경우 호출
- 셰이더, GL 버퍼 객체 등의 WebGL 상태를 초기화하거나 바인딩할 수 있다.
- gl: WebGLRenderingContext
- onDraw({gl, transformer})
- 기본 지도에 장면을 렌더링
- gl: WebGLRenderingContext
- transformer: 지도 좌표를 세계 공간, 카메라 공간, 화면 공간으로 변환하는 데 사용할 수 있는 지도 좌표에서 모델뷰 투영 행렬로 변환하는 도우미 함수를 제공
- onContextLost()
- 렌더링 컨텍스트가 손실될 때 호출
- 기존 GL 상태는 더 이상 필요하지 않으므로 여기에서 삭제
- onStateUpdate({gl})
- 렌러딩 루브 외부의 GL 상태를 업데이트하고 requestStateUpdate가 호출될 때 호출
- gl: WebGLRendewringContext
- onRemove()
- 오버레이가 WebGLOverlayView.setMap(null)을 사용하여 지도에서 삭제될 때 호출
- 모든 중간 객체를 삭제
```javascript
const webglOverlayView = new google.maps.WebGLOverlayView();
webglOverlayView.onAdd = () => {
// Do setup that does not require access to rendering context.
}
webglOverlayView.onContextRestored = ({gl}) => {
// Do setup that requires access to rendering context before onDraw call.
}
webglOverlayView.onStateUpdate = ({gl}) => {
// Do GL state setup or updates outside of the render loop.
}
webglOverlayView.onDraw = ({gl, transformer}) => {
// Render objects.
}
webglOverlayView.onContextLost = () => {
// Clean up pre-existing GL state.
}
webglOverlayView.onRemove = () => {
// Remove all intermediate objects.
}
webglOverlayView.setMap(map);
```
# 좌표 변환
벡터 지도의 위치: 위도, 경도, 고도 혼합
3D 그래픽: 세계 공간, 카메라 공간, 화면 공간에서 지정
지도 -> 3D 그래픽 공간으로 변환
```javascript
const camera = new THREE.PerspectiveCamera();
const matrix = coordinateTransformer.fromLatLngAltitude({
lat: mapOptions.center.lat,
lng: mapOptions.center.lng,
altitude: 120,
});
camera.projectionMatrix = new THREE.Matrix4().fromArray(matrix);
```
# WebGL로 Three.js를 사용하여 지도에 3D 객체를 배치하는 예시 코드
```javascript
const webglOverlayView = new google.maps.WebGLOverlayView();
let scene, renderer, camera, loader;
webglOverlayView.onAdd = () => {
// Set up the Three.js scene.
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera();
const ambientLight = new THREE.AmbientLight( 0xffffff, 0.75 ); // Soft white light.
scene.add(ambientLight);
// Load the 3D model with GLTF Loader from Three.js.
loader = new GLTFLoader();
loader.load("pin.gltf");
}
webglOverlayView.onContextRestored = ({gl}) => {
// Create the Three.js renderer, using the
// maps's WebGL rendering context.
renderer = new THREE.WebGLRenderer({
canvas: gl.canvas,
context: gl,
...gl.getContextAttributes(),
});
renderer.autoClear = false;
}
webglOverlayView.onDraw = ({gl, transformer}) => {
// Update camera matrix to ensure the model is georeferenced correctly on the map.
const matrix = transformer.fromLatLngAltitude({
lat: mapOptions.center.lat,
lng: mapOptions.center.lng,
altitude: 120,
});
camera.projectionMatrix = new THREE.Matrix4().fromArray(matrix);
// Request a redraw and render the scene.
webglOverlayView.requestRedraw();
renderer.render(scene, camera);
// Always reset the GL state.
renderer.resetState();
}
// Add the overlay to the map.
webglOverlayView.setMap(map);
```
---
# WebGL Overlay View를 사용한 3D 지도 환경 빌드
[link](https://developers.google.com/codelabs/maps-platform/webgl?hl=ko#1)
- [ ] Google Maps Platform 설정
- [ ] API키 생성
- [ ] Node.js 설정
- [ ] Github Clone [webgl](https://github.com/googlecodelabs/maps-platform-101-webgl/): /starter
- [ ] cd /starter
- [ ] npm install
- [ ] npm start
- [ ] API키 추가
- [ ] 지도 ID 생성
- [ ] 지도 ID 설정 (mapOptions.mapId)
- [ ] 지도 표시 확인
- [ ] 기울이기 및 회전 확인 (Shift + 마우스 드래그 or 키보드 화살표 키)