Skip to content

Commit 0d4b97c

Browse files
authored
feat(textures) Add composite texture loaders (#3328)
1 parent b388320 commit 0d4b97c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2320
-120
lines changed

docs/README.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ loaders.gl provides a wide selection of loaders organized into categories:
3535
| ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
3636
| [Table Loaders](/docs/specifications/category-table) | Streaming tabular loaders for [CSV](/docs/modules/csv/api-reference/csv-loader), [JSON](/docs/modules/json/api-reference/json-loader), [Arrow](/docs/modules/arrow/api-reference/arrow-loader) etc |
3737
| [Geospatial Loaders](/docs/specifications/category-gis) | Loaders for geospatial formats such as [GeoJSON](/docs/modules/json/api-reference/geojson-loader) [KML](/docs/modules/kml/api-reference/kml-loader), [WKT/WKB](/docs/modules/wkt/api-reference/wkt-loader), [Mapbox Vector Tiles](/docs/modules/mvt/api-reference/mvt-loader) etc. |
38-
| [Image Loaders](/docs/specifications/category-image) | Loaders for [images](/docs/modules/images/api-reference/image-loader), [compressed textures](/docs/modules/textures/api-reference/compressed-texture-loader), [supercompressed textures (Basis)](/docs/modules/textures/api-reference/basis-loader). Utilities for [mipmapped arrays](/docs/modules/textures/api-reference/load-image-array), [cubemaps](/docs/modules/textures/api-reference/load-image-cube), [binary images](/docs/modules/images/api-reference/binary-image-api) and more. |
38+
| [Image Loaders](/docs/specifications/category-image) | Loaders for [images](/docs/modules/images/api-reference/image-loader), [compressed textures](/docs/modules/textures/api-reference/compressed-texture-loader), [supercompressed textures (Basis)](/docs/modules/textures/api-reference/basis-loader), [composite image textures](/docs/modules/textures/api-reference/image-texture-cube-loader), [binary images](/docs/modules/images/api-reference/binary-image-api) and more. |
3939
| [Pointcloud and Mesh Loaders](/docs/specifications/category-mesh) | Loaders for point cloud and simple mesh formats such as [Draco](/docs/modules/draco/api-reference/draco-loader), [LAS](/docs/modules/las/api-reference/las-loader), [PCD](/docs/modules/pcd/api-reference/pcd-loader), [PLY](/docs/modules/ply/api-reference/ply-loader), [OBJ](/docs/modules/obj/api-reference/obj-loader), and [Terrain](/docs/modules/terrain/api-reference/terrain-loader). |
4040
| [Scenegraph Loaders](/docs/specifications/category-scenegraph) | [glTF](/docs/modules/gltf/api-reference/gltf-loader) loader |
4141
| [Tiled Data Loaders](/docs/specifications/category-3d-tiles) | Loaders for 3D tile formats such as [3D Tiles](/docs/modules/3d-tiles/api-reference/tiles-3d-loader), [I3S](/docs/modules/i3s/api-reference/i3s-loader) and potree |

docs/developer-guide/composite-loaders.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,25 @@ The `parse*WithContext()` functions exported by `@loaders.gl/loader-utils` are t
4444
## LoaderContext
4545

4646
When a loader is being called (i.e. one of its `parse*()` functions is being called), a `LoaderContext` object is supplied.
47+
48+
## Base URL Handling
49+
50+
Composite loaders should resolve relative sub-resources from `context.baseUrl`.
51+
52+
- `load(url, loader)` derives the effective base URL from the top-level resource URL and stores it on `context.baseUrl`
53+
- subloader and associated-resource resolution should prefer `context.baseUrl`
54+
- `options.core.baseUrl` is only a fallback for entrypoints that do not have a source URL, such as `parse(text, loader, options)`
55+
- once a loader has a context, it should not keep forwarding `core.baseUrl` into subloader options; child loads should resolve from their own context instead
56+
57+
This keeps base URL state in one place and avoids passing ad hoc base values between composite loaders.
58+
59+
## Forwarding Loader Lists
60+
61+
When a composite loader parses sub-resources, it should preserve the top-level loader list so callers can provide additional member loaders.
62+
63+
- prefer calling subloaders with an array such as `[ImageLoader]`, not a single forced loader
64+
- preserve `context.loaders` so caller-supplied loaders can participate in selection
65+
- when possible, parse the fetched `Response` rather than a detached `ArrayBuffer`, so subloader selection can still use the member URL and MIME type
66+
- if a child resource has its own URL, update the child context so downstream loaders see the correct `context.url` and `context.baseUrl`
67+
68+
This pattern lets a composite loader provide a default member loader while still allowing applications to extend subresource handling.

docs/docs-sidebar.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -429,9 +429,10 @@
429429
"items": [
430430
"modules/textures/README",
431431
"modules/textures/api-reference/radiance-hdr-loader",
432-
"modules/textures/api-reference/load-image",
433-
"modules/textures/api-reference/load-image-array",
434-
"modules/textures/api-reference/load-image-cube"
432+
"modules/textures/api-reference/texture-loader",
433+
"modules/textures/api-reference/texture-array-loader",
434+
"modules/textures/api-reference/texture-cube-loader",
435+
"modules/textures/api-reference/texture-cube-array-loader"
435436
]
436437
},
437438
{

docs/modules/gltf/api-reference/post-process-gltf.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ Remarks:
9999
## Images
100100

101101
- `image.image` - Populated from the supplied `gltf.images` array. This array is populated by the `GLTFLoader` via `options.loadImages: true`):
102-
- `image.uri` - If loaded image in the `images` array is not available, uses `gltf.baseUri` or `options.baseUri` is available, to resolve a relative URI and replaces this value.
102+
- `image.uri` - If the loaded image in the `images` array is not available, uses `gltf.baseUri` to resolve a relative URI and replaces this value.
103103

104104
### Materials
105105

docs/modules/textures/README.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ The `@loaders.gl/textures` module handles the following formats:
4141
| [`CompressedTextureLoader`](/docs/modules/textures/api-reference/compressed-texture-loader) | KTX, DDS and PVR mip chains as `TextureLevel[]` |
4242
| [`RadianceHDRLoader`](/docs/modules/textures/api-reference/radiance-hdr-loader) | Radiance `.hdr` textures as `Texture` |
4343
| [`CrunchWorkerLoader`](/docs/modules/textures/api-reference/crunch-loader) | Crunch mip chains as `TextureLevel[]` |
44+
| [`TextureLoader`](/docs/modules/textures/api-reference/texture-loader) | Manifest-driven single image or mip chain |
45+
| [`TextureArrayLoader`](/docs/modules/textures/api-reference/texture-array-loader) | Manifest-driven texture arrays |
46+
| [`TextureCubeLoader`](/docs/modules/textures/api-reference/texture-cube-loader) | Manifest-driven cubemaps |
47+
| [`TextureCubeArrayLoader`](/docs/modules/textures/api-reference/texture-cube-array-loader) | Manifest-driven cube arrays |
4448

4549
## Return Types
4650

@@ -72,19 +76,18 @@ A `TextureLevel` describes one mip level of one texture image.
7276

7377
See [`BasisLoader`](/docs/modules/textures/api-reference/basis-loader) and [`CompressedTextureLoader`](/docs/modules/textures/api-reference/compressed-texture-loader) for loader-specific options and return shapes.
7478

75-
## Texture APIs
79+
## Composite Image Loaders
7680

77-
The textures API offers functions to load "composite" images for WebGL textures, cube textures and image mip levels.
81+
The textures module also includes manifest-driven loaders for composite image textures:
7882

79-
These functions take a `getUrl` parameter that enables the app to supply the url for each "sub-image", and return a single promise enabling applications to for instance load all the faces of a cube texture, with one image for each mip level for each face in a single async operation.
83+
- [`TextureLoader`](/docs/modules/textures/api-reference/texture-loader) for a single image or mip chain
84+
- [`TextureArrayLoader`](/docs/modules/textures/api-reference/texture-array-loader) for texture arrays, including mipmapped layers
85+
- [`TextureCubeLoader`](/docs/modules/textures/api-reference/texture-cube-loader) for cubemaps, including mipmapped faces
86+
- [`TextureCubeArrayLoader`](/docs/modules/textures/api-reference/texture-cube-array-loader) for cube arrays
8087

81-
| Function | Description |
82-
| ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
83-
| [`loadImage`](/docs/modules/textures/api-reference/load-image) | Load a single image |
84-
| [`loadImageArray`](/docs/modules/textures/api-reference/load-image-array) | Load an array of images, e.g. for a `Texture2DArray` or `Texture3D` |
85-
| [`loadImageCube`](/docs/modules/textures/api-reference/load-image-cube) | Load a map of 6 images for the faces of a cube map, or a map of 6 arrays of images for the mip levels of the 6 faces. |
86-
87-
As with all loaders.gl functions, while these functions are intended for use in WebGL applications, they do not call any WebGL functions, and do not actually create any WebGL textures..
88+
These loaders resolve relative member URLs against the manifest URL, or against `options.core.baseUrl` when parsing an in-memory manifest.
89+
Member assets are parsed with `ImageLoader` by default, and additional loaders passed to top-level `load()` are also available for manifest members.
90+
They return schema `Texture` objects rather than raw image trees.
8891

8992
## Attributions
9093

docs/modules/textures/api-reference/radiance-hdr-loader.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ Loader for Radiance RGBE `.hdr` textures.
88

99
See also: [`Radiance HDR`](/docs/modules/textures/formats/hdr)
1010

11-
| Loader | Characteristic |
12-
| -------------- | ---------------------------- |
13-
| File Format | Radiance HDR / RGBE |
14-
| File Extension | `.hdr` |
15-
| File Type | Binary |
16-
| Data Format | `Texture` |
17-
| Supported APIs | `load`, `parse`, `parseSync` |
11+
| Loader | Characteristic |
12+
| -------------- | ----------------------------------------------------------- |
13+
| File Format | Radiance HDR / RGBE |
14+
| File Extension | `.hdr` |
15+
| File Type | Binary |
16+
| Data Format | [`Texture`](/docs/modules/textures/README#texture-category) |
17+
| Supported APIs | `load`, `parse`, `parseSync` |
1818

1919
## Usage
2020

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# TextureArrayLoader
2+
3+
<p class="badges">
4+
<img src="https://img.shields.io/badge/From-v4.4-blue.svg?style=flat-square" alt="From-v4.4" />
5+
</p>
6+
7+
A loader for texture arrays described by a JSON manifest.
8+
9+
| Loader | Characteristic |
10+
| -------------- | ----------------------------------------------------------- |
11+
| File Format | JSON manifest |
12+
| File Extension | `.json` |
13+
| File Type | Text |
14+
| Data Format | [`Texture`](/docs/modules/textures/README#texture-category) |
15+
| Supported APIs | `load`, `parse` |
16+
17+
## Usage
18+
19+
```typescript
20+
import {load} from '@loaders.gl/core';
21+
import {TextureArrayLoader} from '@loaders.gl/textures';
22+
23+
const images = await load('texture-array.image-texture-array.json', TextureArrayLoader);
24+
```
25+
26+
Member images are parsed with `ImageLoader` by default. If you pass a loader array to `load()`, those additional loaders are also available for array layers and mip levels.
27+
28+
## Manifest
29+
30+
Texture array:
31+
32+
```json
33+
{
34+
"shape": "image-texture-array",
35+
"layers": ["layer-0.png", "layer-1.png"]
36+
}
37+
```
38+
39+
Texture array with mipmaps:
40+
41+
```json
42+
{
43+
"shape": "image-texture-array",
44+
"layers": [
45+
["layer-0-0.png", "layer-0-1.png"],
46+
["layer-1-0.png", "layer-1-1.png"]
47+
]
48+
}
49+
```
50+
51+
Each entry in `layers` can be either:
52+
53+
- a single image path
54+
- an array of image paths representing mip levels
55+
- a template source object
56+
57+
Template source example:
58+
59+
```json
60+
{
61+
"shape": "image-texture-array",
62+
"layers": [
63+
{"mipLevels": "auto", "template": "layer-{index}-{lod}.png"},
64+
{"mipLevels": "auto", "template": "layer-{index}-{lod}.png"}
65+
]
66+
}
67+
```
68+
69+
Supported template placeholders are `{lod}` and `{index}`.
70+
Use `\\{` and `\\}` to include literal braces in filenames.
71+
72+
## Options
73+
74+
| Option | Type | Default | Description |
75+
| -------------- | -------- | ------- | ---------------------------------------------------------------------------------- |
76+
| `core.baseUrl` | `string` | - | Base URL used to resolve relative member paths when parsing an in-memory manifest. |
77+
78+
## Output
79+
80+
Returns a `Texture` with:
81+
82+
- `shape: 'texture'`
83+
- `type: '2d-array'`
84+
- `data`: one mip chain per array layer
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# TextureCubeArrayLoader
2+
3+
<p class="badges">
4+
<img src="https://img.shields.io/badge/From-v4.4-blue.svg?style=flat-square" alt="From-v4.4" />
5+
</p>
6+
7+
A loader for texture cube arrays described by a JSON manifest.
8+
9+
| Loader | Characteristic |
10+
| -------------- | ----------------------------------------------------------- |
11+
| File Format | JSON manifest |
12+
| File Extension | `.json` |
13+
| File Type | Text |
14+
| Data Format | [`Texture`](/docs/modules/textures/README#texture-category) |
15+
| Supported APIs | `load`, `parse` |
16+
17+
## Usage
18+
19+
```typescript
20+
import {load} from '@loaders.gl/core';
21+
import {TextureCubeArrayLoader} from '@loaders.gl/textures';
22+
23+
const imageCubeArray = await load(
24+
'environment.image-texture-cube-array.json',
25+
TextureCubeArrayLoader
26+
);
27+
```
28+
29+
Member faces are parsed with `ImageLoader` by default. If you pass a loader array to `load()`, those additional loaders are also available for cube-array faces and mip levels.
30+
31+
## Manifest
32+
33+
```json
34+
{
35+
"shape": "image-texture-cube-array",
36+
"layers": [
37+
{
38+
"faces": {
39+
"+X": "sky-right.png",
40+
"-X": "sky-left.png",
41+
"+Y": "sky-top.png",
42+
"-Y": "sky-bottom.png",
43+
"+Z": "sky-front.png",
44+
"-Z": "sky-back.png"
45+
}
46+
},
47+
{
48+
"faces": {
49+
"+X": "irr-right.png",
50+
"-X": "irr-left.png",
51+
"+Y": "irr-top.png",
52+
"-Y": "irr-bottom.png",
53+
"+Z": "irr-front.png",
54+
"-Z": "irr-back.png"
55+
}
56+
}
57+
]
58+
}
59+
```
60+
61+
Each layer is a cubemap manifest fragment. Each face entry can be either:
62+
63+
- a single image path
64+
- an array of image paths representing mip levels
65+
- a template source object
66+
67+
Template source example:
68+
69+
```json
70+
{
71+
"shape": "image-texture-cube-array",
72+
"layers": [
73+
{
74+
"faces": {
75+
"+X": {"mipLevels": "auto", "template": "cube-{index}-{face}-{lod}.png"},
76+
"-X": {"mipLevels": "auto", "template": "cube-{index}-{face}-{lod}.png"},
77+
"+Y": {"mipLevels": "auto", "template": "cube-{index}-{face}-{lod}.png"},
78+
"-Y": {"mipLevels": "auto", "template": "cube-{index}-{face}-{lod}.png"},
79+
"+Z": {"mipLevels": "auto", "template": "cube-{index}-{face}-{lod}.png"},
80+
"-Z": {"mipLevels": "auto", "template": "cube-{index}-{face}-{lod}.png"}
81+
}
82+
}
83+
]
84+
}
85+
```
86+
87+
Supported template placeholders are `{lod}`, `{index}`, `{face}`, `{direction}`, `{axis}`, and `{sign}`.
88+
Use `\\{` and `\\}` to include literal braces in filenames.
89+
90+
## Options
91+
92+
| Option | Type | Default | Description |
93+
| -------------- | -------- | ------- | ---------------------------------------------------------------------------------- |
94+
| `core.baseUrl` | `string` | - | Base URL used to resolve relative member paths when parsing an in-memory manifest. |
95+
96+
## Output
97+
98+
Returns a `Texture` with:
99+
100+
- `shape: 'texture'`
101+
- `type: 'cube-array'`
102+
- `data`: one cubemap per layer, with one mip chain per face

0 commit comments

Comments
 (0)