# TerrainRGBMeshPlugin

class in `3d-tiles-renderer/three/plugins`

```js
import { TerrainRGBMeshPlugin } from '3d-tiles-renderer/three/plugins';
```

Generates terrain tiles from raster Terrain-RGB elevation tiles. Each elevation texture is
shared by multiple layers of sub tiles that displace a smooth surface mesh on the GPU with a
subview of the texture, so elevation scale and seam updates only require texture changes.

> [!NOTE]
> Enabling frustum culling on the tile meshes is not supported since the geometry bounds do not
> include the gpu displacement. Culling is handled by the tile traversal.

> [!NOTE]
> Debug bounding volume visualizations, such as those from DebugTilesPlugin, may not display
> correctly after changing the height scale since they are not rebuilt when the tile bounding
> volumes update.

Example: Building terrain from Terrain-RGB encoded elevation tiles

```js
import { AmbientLight, DirectionalLight } from 'three';
import { TilesRenderer, GlobeControls } from '3d-tiles-renderer/three';
import { TerrainRGBMeshPlugin, XYZTilesOverlay } from '3d-tiles-renderer/three/plugins';

// scene, camera and renderer are initialized here

const URL = 'https://terrain.reearth.land/mapterhorn-egm08/mapbox/elevation/{z}/{x}/{y}.png';
const SATELLITE_URL = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}';

const light = new DirectionalLight( 0xffffff, 2 );
light.position.set( 1, 2, 3 );
scene.add( light, new AmbientLight( 0xffffff, 0.5 ) );

const tiles = new TilesRenderer();
tiles.registerPlugin( new TerrainRGBMeshPlugin( {
	url: URL,
	tileDimension: 512,
	maxZoom: 14,
	overlay: new XYZTilesOverlay( { url: SATELLITE_URL } ),
	applyOverlayTexture: true,
} ) );
tiles.setCamera( camera );
tiles.group.rotation.x = - Math.PI / 2;
scene.add( tiles.group );

camera.position.set( 4407016, 4564736, - 589979 );
camera.quaternion.set( - 0.2687, - 0.8123, - 0.0193, 0.5172 );

const controls = new GlobeControls( scene, camera, renderer.domElement );
controls.setEllipsoid( tiles.ellipsoid, tiles.group );
controls.enableDamping = true;

renderer.setAnimationLoop( () => {

	controls.update();
	camera.updateMatrixWorld();
	tiles.setResolutionFromRenderer( camera, renderer );
	tiles.update();
	renderer.render( scene, camera );

} );
```

## Constructor

```js
new TerrainRGBMeshPlugin( options?: Object )
```

- `options`, `Object`, optional
  - `url`, `string`: XYZ url template, e.g. `.../{z}/{x}/{y}.png`.
  - `tileDimension`, `number`, optional, default `256`: Source tile pixel size.
  - `maxZoom`, `number`, optional, default `15`: Highest zoom level the source provides.
  - `heightScale`, `number`, optional, default `1`: Factor applied to the meter elevations. A pure vertical
  exaggeration on the ellipsoid, while planar projections need the meters-to-world conversion
  folded in. Can be adjusted dynamically.
  - `overlay`, `ImageOverlay`, optional, default `null`: Overlay used to texture the tiles when
  `applyOverlayTexture` is enabled.
  - `applyOverlayTexture`, `boolean`, optional, default `false`: Whether to apply the overlay texture.
  - `unlit`, `boolean`, optional, default `false`: Render the tiles without lighting or terrain normals.
  - `projection`, `'ellipsoid' | 'source' | string`, optional, default `'ellipsoid'`: Display the tiles on the
  ellipsoid, on a plane in the source projection, or on a plane in the named projection scheme.
  - `endCaps`, `boolean`, optional, default `true`: Snap poles to ±90° lat.
  - `useRecommendedSettings`, `boolean`, optional, default `true`: Apply recommended TilesRenderer settings.

## Methods

### .sampleCartographicElevation

```js
.sampleCartographicElevation( lat: number, lon: number ): number | null
```

Samples the loaded elevation data at the given cartographic point using the finest loaded
texture covering it. The height scale is applied so the result matches the displaced surface.

- `lat`, `number`: Latitude in radians.
- `lon`, `number`: Longitude in radians.

Returns `number | null`: The elevation, or `null` when no data covering the point is loaded.
