# Ground and water

> Reference for Slab, Terrain, Water, useWaves, useShore, smoothOutline and the Outline, HeightAt, WaveOptions, Waves and ShoreField types: every prop and default.

```ts
import { Slab, smoothOutline, Terrain, useShore, useWaves, Water } from "@apricot/react";
import type { HeightAt, Outline, ShoreField, SlabProps, TerrainProps, WaterProps, WaveOptions, Waves } from "@apricot/react";
```

All distances are metres. Shapes on the ground are outlines in the x–z plane.

## Types

| Type | Definition |
| --- | --- |
| `Outline` | `readonly (readonly [x: number, z: number])[]`: corners in order round a shape, closed (the last joins the first). Any shape, bays included |
| `HeightAt` | `(x: number, z: number) => number`: the ground's height at a point |

## `smoothOutline(outline, segments = 96)`

Returns `outline` with its corners rounded into a smooth closed curve through them, as `segments` points. Draw an island's shore from a handful of points.

## `Slab`

Flat ground in any shape, standing up from its position: an island, a lawn, a deck round a pool. Its top is at `position.y + height`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `outline` | `Outline` | required | Its shape on the ground |
| `height` | metres | `0.2` | How thick |
| `holes` | `Outline[]` | none | Shapes cut through it |
| `bevel` | metres | `0.03` | Rounding of its edges |

Plus every shape prop: `material`, `color`, `onPress`, `name`, `visible`, shadows, transforms, `ref` ([Objects](https://matthiasbrandolin.dev/apricot/reference/objects#shared-shape-props)). Changing the outline rebuilds it.

## `Terrain`

A tile of ground of any height, cut square at its edges like a slice of the earth, coloured point by point.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `size` | `[width, depth]` | required | Along x and z, centred on its position |
| `height` | `HeightAt` | required | The ground's height at each point |
| `color` | `(x, z, y) => colour` | white | The top's colour at each point |
| `sides` | `(y) => colour` | the top's edge colour | The cut's colour at each height: layers |
| `spacing` | metres | `0.1` | Distance between its points |
| `base` | metres | 0.2 below its lowest point | How far down its sides reach |
| `roughness` | 0–1 | `0.9` | |
| `water` | object | none | Water in it up to `level`: see below |
| `name`, `ref` | | | |

Plus transforms and shadow props.

`water`:

| Field | Default | Description |
| --- | --- | --- |
| `level` | required | Height of the water's surface |
| `top` | | Colour of the water's depth at the surface, seen in the cut |
| `deep` | | Colour further down |
| `fade` | `1` | Metres of depth until it is all `deep` |
| `clarity` | `0.25` | How much of what is behind shows through, 0–1 |

It draws the water's depth in the cut only; add a `<Water>` of the same size at `level` for the surface.

> [!IMPORTANT]
> `height`, `color` and `sides` are compared by identity. Define them outside the component (or memoise them): a new function rebuilds the terrain.

## `Water`

A water surface: the sea, a pool, a pond. It lies level and is moved, not turned.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `size` | `[width, depth]` | required | Centred on its position |
| `position` | `Vec3` or shared value | `[0, 0, 0]` | Its middle; `y` is the water level |
| `waves` | `Waves` | still | From `useWaves`, shared with floating things |
| `shore` | `ShoreField` | none | From `useShore`: shallows, deep water and foam |
| `shallow` | colour | bright turquoise | Over the shallows, or looked into from above |
| `deep` | colour | azure blue | Out at sea, or seen at a slant |
| `beach` | colour | pale aqua | Where it laps the sand (with `shore`) |
| `foam` | colour or `false` | white | Foam along the shore |
| `caustics` | 0–1 | `0.6` | Light dancing on the bottom of the shallows (with `shore`) |
| `glow` | number | `0.35` | How much it glows with its own colour |
| `clarity` | 0–1 | `0` | How much you see through it |
| `sparkle` | 0–1 | `0.5` | A pale glint on the crests |
| `spacing` | metres | `0.25` | Distance between its points: finer carries shorter waves |
| `ref` | `Ref<SceneObject>` | | |

While it has waves, the scene keeps rendering.

## `useWaves(options?)`

Returns a `Waves` object, made once and changed live when the options change (no new shader).

| `WaveOptions` | Default | Description |
| --- | --- | --- |
| `height` | `0.06` | Crest height above the middle. `0`: still water |
| `length` | `2.5` | Crest to crest |
| `speed` | `0.8` | Metres per second |
| `direction` | `0` | Degrees round the vertical; `0` travels towards +x |

`Waves` methods, for your own floating things in `useFrame`:

| Method | Returns |
| --- | --- |
| `heightAt(x, z)` | The water's height above its level at that point, now |
| `slopeAt(x, z)` | `[alongX, alongZ]`: how steeply it rises there, to tilt what floats |
| `set(options)` | Changes the waves |

## `useShore(land, bounds, options?)`

Measures how far each point of `bounds` is from land, once (again when the inputs change). Returns a `ShoreField` for `<Water shore>`.

| Argument | Type | Description |
| --- | --- | --- |
| `land` | `Outline[]` or `(x, z) => boolean` | The land's outlines, or a test (true on land). Keep a test function stable |
| `bounds` | `[minX, minZ, maxX, maxZ]` | The area measured. Past it, water counts as far from shore |
| `options.reach` | metres, default `4` | How far out the water deepens from the shore |
| `options.size` | texels, default `128` | The field's resolution |

`ShoreField`: `{ texture, bounds, reach }`.

## Placement on ground and water

`<Placement areas zones snaps>` and `<Placeable on="water">`: see [Placement reference](https://matthiasbrandolin.dev/apricot/reference/placement#areas-zones-and-snap-points).

## Related

- [Ground and water guide](https://matthiasbrandolin.dev/apricot/guides/ground-and-water).
- [Core reference](https://matthiasbrandolin.dev/apricot/reference/core): `createTerrainGeometry`, `createWaterMaterial`, `createShoreField`, `createSlabGeometry`.
