Skip to content

Commit 7359625

Browse files
authored
KTX2Loader: Add WebGPU support. (#25867)
* KTX2Loader: Add WebGPU support. * Examples: Clean up.
1 parent f2850ea commit 7359625

File tree

2 files changed

+69
-32
lines changed

2 files changed

+69
-32
lines changed

examples/jsm/loaders/KTX2Loader.js

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -112,21 +112,37 @@ class KTX2Loader extends Loader {
112112

113113
detectSupport( renderer ) {
114114

115-
this.workerConfig = {
116-
astcSupported: renderer.extensions.has( 'WEBGL_compressed_texture_astc' ),
117-
etc1Supported: renderer.extensions.has( 'WEBGL_compressed_texture_etc1' ),
118-
etc2Supported: renderer.extensions.has( 'WEBGL_compressed_texture_etc' ),
119-
dxtSupported: renderer.extensions.has( 'WEBGL_compressed_texture_s3tc' ),
120-
bptcSupported: renderer.extensions.has( 'EXT_texture_compression_bptc' ),
121-
pvrtcSupported: renderer.extensions.has( 'WEBGL_compressed_texture_pvrtc' )
122-
|| renderer.extensions.has( 'WEBKIT_WEBGL_compressed_texture_pvrtc' )
123-
};
115+
if ( renderer.isWebGPURenderer === true ) {
124116

117+
const adapter = renderer._adapter;
125118

126-
if ( renderer.capabilities.isWebGL2 ) {
119+
this.workerConfig = {
120+
astcSupported: adapter.features.has( 'texture-compression-astc' ),
121+
etc1Supported: false,
122+
etc2Supported: adapter.features.has( 'texture-compression-etc2' ),
123+
dxtSupported: adapter.features.has( 'texture-compression-bc' ),
124+
bptcSupported: false,
125+
pvrtcSupported: false
126+
};
127127

128-
// https://github.com/mrdoob/three.js/pull/22928
129-
this.workerConfig.etc1Supported = false;
128+
} else {
129+
130+
this.workerConfig = {
131+
astcSupported: renderer.extensions.has( 'WEBGL_compressed_texture_astc' ),
132+
etc1Supported: renderer.extensions.has( 'WEBGL_compressed_texture_etc1' ),
133+
etc2Supported: renderer.extensions.has( 'WEBGL_compressed_texture_etc' ),
134+
dxtSupported: renderer.extensions.has( 'WEBGL_compressed_texture_s3tc' ),
135+
bptcSupported: renderer.extensions.has( 'EXT_texture_compression_bptc' ),
136+
pvrtcSupported: renderer.extensions.has( 'WEBGL_compressed_texture_pvrtc' )
137+
|| renderer.extensions.has( 'WEBKIT_WEBGL_compressed_texture_pvrtc' )
138+
};
139+
140+
if ( renderer.capabilities.isWebGL2 ) {
141+
142+
// https://github.com/mrdoob/three.js/pull/22928
143+
this.workerConfig.etc1Supported = false;
144+
145+
}
130146

131147
}
132148

examples/webgpu_sandbox.html

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import * as THREE from 'three';
2929
import { timerLocal, vec2, uv, texture, mix, checker, normalLocal, positionLocal, color, oscSine, attribute, MeshBasicNodeMaterial, PointsNodeMaterial, LineBasicNodeMaterial } from 'three/nodes';
3030

31-
import { DDSLoader } from 'three/addons/loaders/DDSLoader.js';
31+
import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js';
3232

3333
import WebGPU from 'three/addons/capabilities/WebGPU.js';
3434
import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
@@ -39,7 +39,7 @@
3939

4040
init();
4141

42-
function init() {
42+
async function init() {
4343

4444
if ( WebGPU.isAvailable() === false ) {
4545

@@ -55,6 +55,15 @@
5555
scene = new THREE.Scene();
5656
scene.background = new THREE.Color( 0x222222 );
5757

58+
//
59+
60+
renderer = new WebGPURenderer( { requiredFeatures: [ 'texture-compression-bc', 'texture-compression-astc' ] } );
61+
renderer.setPixelRatio( window.devicePixelRatio );
62+
renderer.setSize( window.innerWidth, window.innerHeight );
63+
renderer.setAnimationLoop( animate );
64+
document.body.appendChild( renderer.domElement );
65+
await renderer.init();
66+
5867
// textures
5968

6069
const textureLoader = new THREE.TextureLoader();
@@ -67,10 +76,11 @@
6776
textureDisplace.wrapS = THREE.RepeatWrapping;
6877
textureDisplace.wrapT = THREE.RepeatWrapping;
6978

70-
// compressed texture
79+
const ktxLoader = new KTX2Loader()
80+
.setTranscoderPath( 'jsm/libs/basis/' )
81+
.detectSupport( renderer );
7182

72-
const ddsLoader = new DDSLoader();
73-
const dxt5Texture = ddsLoader.load( './textures/compressed/explosion_dxt5_mip.dds' );
83+
const ktxTexture = await ktxLoader.loadAsync( './textures/compressed/sample_uastc_zstd.ktx2' );
7484

7585
// box mesh
7686

@@ -114,7 +124,6 @@
114124
const geometryPlane = new THREE.PlaneGeometry();
115125
const materialPlane = new MeshBasicNodeMaterial();
116126
materialPlane.colorNode = texture( createDataTexture() ).add( color( 0x0000FF ) );
117-
materialPlane.opacityNode = texture( dxt5Texture ).a;
118127
materialPlane.transparent = true;
119128

120129
const plane = new THREE.Mesh( geometryPlane, materialPlane );
@@ -124,14 +133,15 @@
124133
// compressed texture
125134

126135
const materialCompressed = new MeshBasicNodeMaterial();
127-
materialCompressed.colorNode = texture( dxt5Texture );
136+
materialCompressed.colorNode = texture( ktxTexture );
128137
materialCompressed.emissiveNode = oscSine().mix( color( 0x663300 ), color( 0x0000FF ) );
129138
materialCompressed.alphaTestNode = oscSine();
130139
materialCompressed.transparent = true;
131140

132-
const boxCompressed = new THREE.Mesh( geometryBox, materialCompressed );
133-
boxCompressed.position.set( - 2, 1, 0 );
134-
scene.add( boxCompressed );
141+
const geo = flipY( new THREE.PlaneGeometry() );
142+
const planeCompressed = new THREE.Mesh( geo, materialCompressed );
143+
planeCompressed.position.set( - 2, 1, 0 );
144+
scene.add( planeCompressed );
135145

136146
// points
137147

@@ -171,14 +181,6 @@
171181
line.position.set( 2, 1, 0 );
172182
scene.add( line );
173183

174-
//
175-
176-
renderer = new WebGPURenderer( { requiredFeatures: [ 'texture-compression-bc' ] } );
177-
renderer.setPixelRatio( window.devicePixelRatio );
178-
renderer.setSize( window.innerWidth, window.innerHeight );
179-
renderer.setAnimationLoop( animate );
180-
document.body.appendChild( renderer.domElement );
181-
182184
window.addEventListener( 'resize', onWindowResize );
183185

184186
}
@@ -194,8 +196,12 @@
194196

195197
function animate() {
196198

197-
box.rotation.x += 0.01;
198-
box.rotation.y += 0.02;
199+
if ( box ) {
200+
201+
box.rotation.x += 0.01;
202+
box.rotation.y += 0.02;
203+
204+
}
199205

200206
renderer.render( scene, camera );
201207

@@ -232,6 +238,21 @@
232238

233239
}
234240

241+
/** Correct UVs to be compatible with `flipY=false` textures. */
242+
function flipY( geometry ) {
243+
244+
const uv = geometry.attributes.uv;
245+
246+
for ( let i = 0; i < uv.count; i ++ ) {
247+
248+
uv.setY( i, 1 - uv.getY( i ) );
249+
250+
}
251+
252+
return geometry;
253+
254+
}
255+
235256
</script>
236257
</body>
237258
</html>

0 commit comments

Comments
 (0)