diff --git a/examples/jsm/loaders/KTX2Loader.js b/examples/jsm/loaders/KTX2Loader.js index e9aa3d93a9d4d9..80225defed1f93 100644 --- a/examples/jsm/loaders/KTX2Loader.js +++ b/examples/jsm/loaders/KTX2Loader.js @@ -112,21 +112,37 @@ class KTX2Loader extends Loader { detectSupport( renderer ) { - this.workerConfig = { - astcSupported: renderer.extensions.has( 'WEBGL_compressed_texture_astc' ), - etc1Supported: renderer.extensions.has( 'WEBGL_compressed_texture_etc1' ), - etc2Supported: renderer.extensions.has( 'WEBGL_compressed_texture_etc' ), - dxtSupported: renderer.extensions.has( 'WEBGL_compressed_texture_s3tc' ), - bptcSupported: renderer.extensions.has( 'EXT_texture_compression_bptc' ), - pvrtcSupported: renderer.extensions.has( 'WEBGL_compressed_texture_pvrtc' ) - || renderer.extensions.has( 'WEBKIT_WEBGL_compressed_texture_pvrtc' ) - }; + if ( renderer.isWebGPURenderer === true ) { + const adapter = renderer._adapter; - if ( renderer.capabilities.isWebGL2 ) { + this.workerConfig = { + astcSupported: adapter.features.has( 'texture-compression-astc' ), + etc1Supported: false, + etc2Supported: adapter.features.has( 'texture-compression-etc2' ), + dxtSupported: adapter.features.has( 'texture-compression-bc' ), + bptcSupported: false, + pvrtcSupported: false + }; - // https://github.com/mrdoob/three.js/pull/22928 - this.workerConfig.etc1Supported = false; + } else { + + this.workerConfig = { + astcSupported: renderer.extensions.has( 'WEBGL_compressed_texture_astc' ), + etc1Supported: renderer.extensions.has( 'WEBGL_compressed_texture_etc1' ), + etc2Supported: renderer.extensions.has( 'WEBGL_compressed_texture_etc' ), + dxtSupported: renderer.extensions.has( 'WEBGL_compressed_texture_s3tc' ), + bptcSupported: renderer.extensions.has( 'EXT_texture_compression_bptc' ), + pvrtcSupported: renderer.extensions.has( 'WEBGL_compressed_texture_pvrtc' ) + || renderer.extensions.has( 'WEBKIT_WEBGL_compressed_texture_pvrtc' ) + }; + + if ( renderer.capabilities.isWebGL2 ) { + + // https://github.com/mrdoob/three.js/pull/22928 + this.workerConfig.etc1Supported = false; + + } } diff --git a/examples/webgpu_sandbox.html b/examples/webgpu_sandbox.html index 3ce37d484b61ed..c20d3742f887d2 100644 --- a/examples/webgpu_sandbox.html +++ b/examples/webgpu_sandbox.html @@ -28,7 +28,7 @@ import * as THREE from 'three'; import { timerLocal, vec2, uv, texture, mix, checker, normalLocal, positionLocal, color, oscSine, attribute, MeshBasicNodeMaterial, PointsNodeMaterial, LineBasicNodeMaterial } from 'three/nodes'; - import { DDSLoader } from 'three/addons/loaders/DDSLoader.js'; + import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; import WebGPU from 'three/addons/capabilities/WebGPU.js'; import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js'; @@ -39,7 +39,7 @@ init(); - function init() { + async function init() { if ( WebGPU.isAvailable() === false ) { @@ -55,6 +55,15 @@ scene = new THREE.Scene(); scene.background = new THREE.Color( 0x222222 ); + // + + renderer = new WebGPURenderer( { requiredFeatures: [ 'texture-compression-bc', 'texture-compression-astc' ] } ); + renderer.setPixelRatio( window.devicePixelRatio ); + renderer.setSize( window.innerWidth, window.innerHeight ); + renderer.setAnimationLoop( animate ); + document.body.appendChild( renderer.domElement ); + await renderer.init(); + // textures const textureLoader = new THREE.TextureLoader(); @@ -67,10 +76,11 @@ textureDisplace.wrapS = THREE.RepeatWrapping; textureDisplace.wrapT = THREE.RepeatWrapping; - // compressed texture + const ktxLoader = new KTX2Loader() + .setTranscoderPath( 'jsm/libs/basis/' ) + .detectSupport( renderer ); - const ddsLoader = new DDSLoader(); - const dxt5Texture = ddsLoader.load( './textures/compressed/explosion_dxt5_mip.dds' ); + const ktxTexture = await ktxLoader.loadAsync( './textures/compressed/sample_uastc_zstd.ktx2' ); // box mesh @@ -114,7 +124,6 @@ const geometryPlane = new THREE.PlaneGeometry(); const materialPlane = new MeshBasicNodeMaterial(); materialPlane.colorNode = texture( createDataTexture() ).add( color( 0x0000FF ) ); - materialPlane.opacityNode = texture( dxt5Texture ).a; materialPlane.transparent = true; const plane = new THREE.Mesh( geometryPlane, materialPlane ); @@ -124,14 +133,15 @@ // compressed texture const materialCompressed = new MeshBasicNodeMaterial(); - materialCompressed.colorNode = texture( dxt5Texture ); + materialCompressed.colorNode = texture( ktxTexture ); materialCompressed.emissiveNode = oscSine().mix( color( 0x663300 ), color( 0x0000FF ) ); materialCompressed.alphaTestNode = oscSine(); materialCompressed.transparent = true; - const boxCompressed = new THREE.Mesh( geometryBox, materialCompressed ); - boxCompressed.position.set( - 2, 1, 0 ); - scene.add( boxCompressed ); + const geo = flipY( new THREE.PlaneGeometry() ); + const planeCompressed = new THREE.Mesh( geo, materialCompressed ); + planeCompressed.position.set( - 2, 1, 0 ); + scene.add( planeCompressed ); // points @@ -171,14 +181,6 @@ line.position.set( 2, 1, 0 ); scene.add( line ); - // - - renderer = new WebGPURenderer( { requiredFeatures: [ 'texture-compression-bc' ] } ); - renderer.setPixelRatio( window.devicePixelRatio ); - renderer.setSize( window.innerWidth, window.innerHeight ); - renderer.setAnimationLoop( animate ); - document.body.appendChild( renderer.domElement ); - window.addEventListener( 'resize', onWindowResize ); } @@ -194,8 +196,12 @@ function animate() { - box.rotation.x += 0.01; - box.rotation.y += 0.02; + if ( box ) { + + box.rotation.x += 0.01; + box.rotation.y += 0.02; + + } renderer.render( scene, camera ); @@ -232,6 +238,21 @@ } + /** Correct UVs to be compatible with `flipY=false` textures. */ + function flipY( geometry ) { + + const uv = geometry.attributes.uv; + + for ( let i = 0; i < uv.count; i ++ ) { + + uv.setY( i, 1 - uv.getY( i ) ); + + } + + return geometry; + + } +