Skip to content

WebGPURenderer: Support ExternalTexture with GPUTexture#31653

Merged
sunag merged 2 commits into
mrdoob:devfrom
donmccurdy:feat/externaltexture-webgpu
Aug 16, 2025
Merged

WebGPURenderer: Support ExternalTexture with GPUTexture#31653
sunag merged 2 commits into
mrdoob:devfrom
donmccurdy:feat/externaltexture-webgpu

Conversation

@donmccurdy

@donmccurdy donmccurdy commented Aug 15, 2025

Copy link
Copy Markdown
Collaborator

Related issue:

Adds support for initializing a THREE.ExternalTexture instance with a GPUTexture created by the WebGPU renderer's own device. Provides a fast path for using textures created by other libraries (example: https://ludicon.com/sparkjs/) without extra copies.

Example:

import { Spark } from '@ludicon/spark.js';

const gpuTexture = await spark.encodeTexture( texturePath, { mips: true, srgb: true, flipY: true } );

const texture = new THREE.ExternalTexture( gpuTexture );

On local testing, our textures/uv_grid_opengl.jpg is compressed to BC7 in 0.1 ms (!) on an M1 device.

The code changes required are trivial, but I'm not sure if using THREE.ExternalTexture as proposed in #31595 is semantically right — this is the opposite of a "texture created externally from the renderer context" as the JSDoc suggests... Would it make more sense to use THREE.CompressedTexture? A new THREE.InternalTexture or THREE.GPUTexture class? My (slight) preference would be to keep using THREE.ExternalTexture, but to update the documentation to say "externally from three.js" instead.

@donmccurdy donmccurdy changed the title WebGPURenderer: Support ExternalTexture WebGPURenderer: Support ExternalTexture with GPUTexture Aug 15, 2025
@github-actions

github-actions Bot commented Aug 15, 2025

Copy link
Copy Markdown

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 338.96
79.12
338.91
79.11
-51 B
-16 B
WebGPU 575.35
158.76
575.47
158.8
+121 B
+44 B
WebGPU Nodes 573.96
158.51
574.08
158.56
+121 B
+45 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Before After Diff
WebGL 470.7
113.89
470.7
113.91
+0 B
+23 B
WebGPU 646.42
174.83
646.53
174.86
+105 B
+27 B
WebGPU Nodes 600.6
164.01
600.71
164.04
+105 B
+30 B

@Mugen87

Mugen87 commented Aug 15, 2025

Copy link
Copy Markdown
Collaborator

What kind of object type is gpuTexture returned by spark?

ExternalTexture is intended for the case when external components like third-party projects share the same rendering context and provide raw/native texture objects for use. So GL or GPU texture object.

ExternalTexture is not intended for any other use case. If an external component generates a canvas with color data, CanvasTexture should be used. If the data are represented as (typed) arrays, it should be DataTexture or CompressedTexture depending on whether compression is used or not.

@donmccurdy

Copy link
Copy Markdown
Collaborator Author

Ahh ok, thanks. I'd misread the JSDoc description on ExternalTexture. Spark.js returns a WebGPU GPUTexture, so ExternalTexture would be the right class then!

@Mugen87 Mugen87 added this to the r180 milestone Aug 15, 2025
@sunag sunag merged commit aec0e87 into mrdoob:dev Aug 16, 2025
9 checks passed
@donmccurdy donmccurdy deleted the feat/externaltexture-webgpu branch August 16, 2025 16:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants