Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/tutorials/spine-animation.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ thumb: /img/tutorials/spine-animation/thumbnail.jpg

*Use the panel to pick the animation each skeleton plays, change its speed, and pause it.*

This tutorial plays two skeletal animations made with the [Spine](https://esotericsoftware.com/) editor, using the [playcanvas-spine](https://github.com/playcanvas/playcanvas-spine) plugin. The tank is loaded from a binary `.skel` export, and Celestial Circus from a JSON export. You can explore the finished scene in the [tutorial project](https://playcanvas.com/project/1615675). The [Spine](/user-manual/2D/spine/) page of the User Manual covers the plugin in more detail.
This tutorial plays two skeletal animations made with the [Spine](https://esotericsoftware.com/) editor, using the [playcanvas-spine](https://github.com/playcanvas/playcanvas-spine) plugin. The tank is loaded from a binary `.skel` export, and Celestial Circus from a JSON export. You can explore the finished scene in the [tutorial project](https://playcanvas.com/project/1615675). The [Spine](/user-manual/engine/libraries/spine/) page of the User Manual covers the plugin in more detail.

## Adding the plugin

Expand Down
98 changes: 0 additions & 98 deletions docs/tutorials/tweening.md

This file was deleted.

2 changes: 1 addition & 1 deletion docs/user-manual/2D/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ The [Sprite Editor](/user-manual/2D/sprite-editor) is the tool used to generate

![Spine](/img/user-manual/2D/spine/spine-4-3-example.webp)

[Spine](https://esotericsoftware.com/) is an editor for 2D skeletal animation. The [playcanvas-spine](https://github.com/playcanvas/playcanvas-spine) plugin plays animations exported from Spine, in Editor and engine-only projects. [Read More](/user-manual/2D/spine).
[Spine](https://esotericsoftware.com/) is an editor for 2D skeletal animation. The [playcanvas-spine](https://github.com/playcanvas/playcanvas-spine) plugin plays animations exported from Spine, in Editor and engine-only projects. [Read More](/user-manual/engine/libraries/spine/).
2 changes: 1 addition & 1 deletion docs/user-manual/animation/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The anim component is the same everywhere, but the surfaces expose different amo

:::note

The anim component replaced the older **animation** component, which plays clips without state graphs. That component still works, but use the anim component in new projects. For 2D skeletal animation made with Spine, see [Spine](/user-manual/2D/spine/).
The anim component replaced the older **animation** component, which plays clips without state graphs. That component still works, but use the anim component in new projects. For 2D skeletal animation made with Spine, see [Spine](/user-manual/engine/libraries/spine/).

:::

Expand Down
1 change: 1 addition & 0 deletions docs/user-manual/engine/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ The engine's features are documented by topic, and each topic applies whichever
- [Engine Migrations](migrations.md) — breaking changes and how to update your code.
- [Supported Browsers](supported-browsers.md) — minimum browser versions for WebGL 2 and WebGPU.
- [Developing with AI](developing-with-ai.md) — set up a coding agent on an Engine project and verify its changes.
- [Add-on Libraries](libraries/index.md) — Spine animation, 3D Tiles streaming, tweening and loaders.gl, used alongside the engine.
- [Examples](https://playcanvas.com/examples/) — more than 250 live examples with editable source code.
- [API Reference](https://api.playcanvas.com/engine/) — every class, method and property.

Expand Down
116 changes: 116 additions & 0 deletions docs/user-manual/engine/libraries/3d-tiles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
---
title: 3D Tiles
description: Stream massive 3D datasets, such as photogrammetry, city models and terrain, in the 3D Tiles format with the PlayCanvas renderer of 3DTilesRendererJS.
---

[3D Tiles](https://www.ogc.org/standards/3DTiles) is an open standard for streaming massive 3D datasets, such as photogrammetry captures, city models and terrain. A tileset is a tree of tiles at increasing levels of detail, so a viewer loads only the tiles the camera needs, at the detail the view needs.

[3DTilesRendererJS](https://github.com/NASA-AMMOS/3DTilesRendererJS) by NASA-AMMOS loads and renders 3D Tiles, and includes a renderer for PlayCanvas. It loads the tile content with the engine's glTF parser, so the glTF extensions the engine supports work in tiles too, and it renders with WebGPU and WebGL 2.

## Installation

Install the library and the engine from npm:

```bash
npm install 3d-tiles-renderer playcanvas
```

The PlayCanvas renderer is imported from `3d-tiles-renderer/playcanvas`.

## Rendering a tileset

Create a `TilesRenderer` for the URL of the tileset's `tileset.json`, give it the camera that decides which tiles load, add its root entity to the scene, and update it every frame:

```javascript
import { TilesRenderer } from '3d-tiles-renderer/playcanvas';

const tiles = new TilesRenderer('https://example.com/tileset/tileset.json', app);
tiles.setCamera(camera.camera);
app.root.addChild(tiles.group);

// update the tiles every frame, after the camera has moved
app.on('update', () => {
tiles.update();
});
```

The tiles are loaded as `container` assets, and created as entities with render components under `tiles.group`. An `Application` includes everything they need. An `AppBase` application needs the `RenderComponentSystem`, and the `ContainerHandler` and `TextureHandler` resource handlers.

The tileset is positioned in its own coordinate system, so move, rotate or scale `tiles.group`, or a parent entity, to place it in your scene.

## Settings

| Property | Description |
| --- | --- |
| `errorTarget` | The screen space error, in pixels, that a tile may show before more detailed tiles load in its place. Lower values load more detail and more data. Defaults to 16. |
| `lruCache.minBytesSize`, `lruCache.maxBytesSize` | The memory budget for loaded tiles, 0.3 and 0.4 GiB by default. |
| `fetchOptions` | Options passed to `fetch` for every request, such as `mode`, `credentials` or `headers`. |
| `renderOptions` | Options for the render components of the tiles, such as `castShadows`, `receiveShadows` or `layers`. |
| `assetOptions` | Options for the `container` assets the tiles are loaded as, such as glTF parser callbacks. |

Photogrammetry tiles often carry large textures. When the memory budget is too small for the view, tiles are unloaded to make room for others, and the view may never finish loading. Raise the budget for such tilesets, keeping in mind the memory of the devices you target.

## Compressed content

Tiles with Draco compressed meshes or KTX2 textures need the engine's decoders to be set up before the tiles load, otherwise those tiles fail to load:

```javascript
import { basisInitialize, dracoInitialize } from 'playcanvas';

dracoInitialize({
jsUrl: 'wasm/draco/draco.wasm.js',
wasmUrl: 'wasm/draco/draco.wasm.wasm'
});

basisInitialize({
glueUrl: 'wasm/basis/basis.wasm.js',
wasmUrl: 'wasm/basis/basis.wasm.wasm',
fallbackUrl: 'wasm/basis/basis.js'
});
```

The decoders are not part of the `playcanvas` npm package. You can find them in the engine repository under [`examples/assets/wasm`](https://github.com/playcanvas/engine/tree/main/examples/assets/wasm).

## Customizing loaded tiles

The renderer fires events as it works. The `load-model` event fires for every loaded tile, with the entity created for its content, so you can change its materials. Photogrammetry tiles, for example, are usually unlit, with their color in the emissive map. To light them, so they also receive shadows, move the color to the diffuse map:

```javascript
tiles.on('load-model', ({ scene }) => {
for (const render of scene.findComponents('render')) {
for (const meshInstance of render.meshInstances) {
const material = meshInstance.material;
material.diffuseMap = material.emissiveMap;
material.emissiveMap = null;
material.emissive.set(0, 0, 0);
material.useLighting = true;
material.update();
}
}
});
```

Events can be subscribed to with `on` and `off`, or with `addEventListener` and `removeEventListener`.

## Plugins

Plugins extend the renderer, for example to authenticate with a tile service or to support more tileset features. Register them with `registerPlugin`:

```javascript
tiles.registerPlugin(plugin);
```

The engine-agnostic plugins of the library, in `3d-tiles-renderer/core/plugins`, work with the PlayCanvas renderer. A plugin can also be a plain object with the hooks the renderer calls while it loads the tileset, which is how the Helsinki example below adapts its tileset.

## Limitations

- Only glTF, GLB and B3DM tile content is supported.
- Only `box` and `sphere` bounding volumes are supported. Tiles that have only a `region` volume are not displayed.
- Engine transforms are 32-bit, so tilesets positioned on the globe, in coordinates millions of meters from the origin, are not rendered precisely. Such a tileset needs to be re-centered close to the origin in double precision before the engine sees it, as the Helsinki example does with a plugin.
- Raycasting against the tiles is not supported.

## Examples

<EngineExample id="integrations/mars-3d-tiles" title="Mars 3D Tiles" />

<EngineExample id="integrations/helsinki-3d-tiles" title="Helsinki 3D Tiles" />
17 changes: 17 additions & 0 deletions docs/user-manual/engine/libraries/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: Add-on Libraries
description: Libraries that work alongside the engine - Spine skeletal animation, streaming 3D Tiles with 3DTilesRendererJS, tweening, and loading data with loaders.gl.
---

The engine covers rendering, physics, audio, input and the rest of a real-time app. Some features are better served by a separate library that you add alongside it. PlayCanvas maintains some of these libraries, and others are third-party projects with support for PlayCanvas of their own.

| Library | What it adds | Maintained by |
| --- | --- | --- |
| [Spine](/user-manual/engine/libraries/spine/) | 2D skeletal animation made with the Spine editor, played by the playcanvas-spine plugin | PlayCanvas (plugin), Esoteric Software (Spine) |
| [3D Tiles](/user-manual/engine/libraries/3d-tiles/) | Streaming of massive 3D datasets, such as photogrammetry and city models, with 3DTilesRendererJS | NASA-AMMOS |
| [Tween](/user-manual/engine/libraries/tween/) | Animating entity transforms and other values over time, with playcanvas-tween | PlayCanvas |
| [loaders.gl](/user-manual/engine/libraries/loaders-gl/) | Parsers for many data formats, whose data you turn into engine meshes | vis.gl (OpenJS Foundation) |

These libraries are not part of the `playcanvas` npm package. Each one is installed and versioned on its own, so check which engine versions it supports on its own page or repository.

The **Integrations** category of the [Engine Examples](https://playcanvas.com/examples) shows these libraries in use.
18 changes: 18 additions & 0 deletions docs/user-manual/engine/libraries/loaders-gl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: loaders.gl
description: Parse data formats the engine does not load itself, such as point clouds, with the loaders of loaders.gl, and turn the parsed data into engine meshes.
---

[loaders.gl](https://loaders.gl/) is a collection of loaders for many data formats, from point clouds and meshes to geospatial data and tables. It is part of the vis.gl framework suite, under the OpenJS Foundation.

loaders.gl parses data and nothing more. A loader returns plain JavaScript objects and typed arrays, such as the positions and colors of a point cloud, and does not render anything. To show the data, create an engine [`Mesh`](https://api.playcanvas.com/engine/classes/Mesh.html) from the arrays, and render it with a mesh instance.

The engine loads glTF and GLB models, compressed textures and gaussian splats itself, so prefer its own loaders for those, and reach for loaders.gl for formats the engine does not read.

## Example

The example loads a Draco compressed point cloud with loaders.gl, and renders its points with a custom shader:

<EngineExample id="integrations/loaders-gl" title="loaders.gl" />

See the [loaders.gl documentation](https://loaders.gl/docs) for the available loaders and how to use them.
Loading
Loading