---
# System prepended metadata

title: 3D Web

---

# 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 키보드 화살표 키)