Renders 3D tiles in a web browser

HTML

<script type="importmap">
	{
		"imports": {
			"three": "https://cdn.jsdelivr.net/npm/three/build/three.module.js",
			"three/": "https://cdn.jsdelivr.net/npm/three/",
			"3d-tiles-renderer": "https://cdn.jsdelivr.net/npm/3d-tiles-renderer/src/index.js",
			"3d-tiles-renderer/plugins": "https://cdn.jsdelivr.net/npm/3d-tiles-renderer/src/plugins.js"
		}
	}
</script>

CSS

body {
	  margin: 0;
}

JavaScript

import * as THREE from 'three';
import { GlobeControls, TilesRenderer } from '3d-tiles-renderer';
import { QuantizedMeshPlugin, ImageOverlayPlugin, XYZTilesOverlay, UpdateOnChangePlugin } from '3d-tiles-renderer/plugins';

const width = window.innerWidth;
const height = window.innerHeight;

// camera
const camera = new THREE.PerspectiveCamera( 70, width / height, 0.1, 1000 );
camera.position.set( 524492.548, 163230.476, 6344687.581 );

// renderer
const renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( width, height );
document.body.appendChild( renderer.domElement );

// scene
const scene = new THREE.Scene();

scene.add(new THREE.AmbientLight());

// tiles
const tilesRenderer = new TilesRenderer("https://3d.geo.admin.ch/ch.swisstopo.terrain.3d/v1/layer.json");
tilesRenderer.registerPlugin(new QuantizedMeshPlugin({}));
tilesRenderer.registerPlugin(new UpdateOnChangePlugin());
tilesRenderer.registerPlugin(
			new ImageOverlayPlugin({
				renderer: renderer,
				enableTileSplitting: true,
				overlays: [
					new XYZTilesOverlay({
						url: "https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.swissimage/default/current/3857/{z}/{x}/{y}.jpeg",
						levels: 20,
						dimension: 256,
						color: 0xffffff,
						opacity: 1,
					}),
				],
			})
		);
tilesRenderer.setCamera( camera );
tilesRenderer.setResolutionFromRenderer( camera, renderer );
tilesRenderer.group.rotation.x = -Math.PI / 4;
tilesRenderer.group.rotation.z = 3*Math.PI/2;
scene.add( tilesRenderer.group );

// controls
const controls = new GlobeControls( scene, camera, renderer.domElement );
controls.setEllipsoid( tilesRenderer.ellipsoid, tilesRenderer.group );

// animation
renderer.setAnimationLoop( animate );

function animate() {

	controls.update();
	tilesRenderer.update();

	renderer.render( scene, camera );

}