瀏覽代碼

KTX2Loader: Add WebGPU support. (#25867)

* KTX2Loader: Add WebGPU support.

* Examples: Clean up.
Michael Herzog 2 年之前
父節點
當前提交
7359625c4b
共有 2 個文件被更改,包括 69 次插入32 次删除
  1. 28 12
      examples/jsm/loaders/KTX2Loader.js
  2. 41 20
      examples/webgpu_sandbox.html

+ 28 - 12
examples/jsm/loaders/KTX2Loader.js

@@ -112,21 +112,37 @@ class KTX2Loader extends Loader {
 
 
 	detectSupport( renderer ) {
 	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;
+
+			}
 
 
 		}
 		}
 
 

+ 41 - 20
examples/webgpu_sandbox.html

@@ -28,7 +28,7 @@
 			import * as THREE from 'three';
 			import * as THREE from 'three';
 			import { timerLocal, vec2, uv, texture, mix, checker, normalLocal, positionLocal, color, oscSine, attribute, MeshBasicNodeMaterial, PointsNodeMaterial, LineBasicNodeMaterial } from 'three/nodes';
 			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 WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
@@ -39,7 +39,7 @@
 
 
 			init();
 			init();
 
 
-			function init() {
+			async function init() {
 
 
 				if ( WebGPU.isAvailable() === false ) {
 				if ( WebGPU.isAvailable() === false ) {
 
 
@@ -55,6 +55,15 @@
 				scene = new THREE.Scene();
 				scene = new THREE.Scene();
 				scene.background = new THREE.Color( 0x222222 );
 				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
 				// textures
 
 
 				const textureLoader = new THREE.TextureLoader();
 				const textureLoader = new THREE.TextureLoader();
@@ -67,10 +76,11 @@
 				textureDisplace.wrapS = THREE.RepeatWrapping;
 				textureDisplace.wrapS = THREE.RepeatWrapping;
 				textureDisplace.wrapT = 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
 				// box mesh
 
 
@@ -114,7 +124,6 @@
 				const geometryPlane = new THREE.PlaneGeometry();
 				const geometryPlane = new THREE.PlaneGeometry();
 				const materialPlane = new MeshBasicNodeMaterial();
 				const materialPlane = new MeshBasicNodeMaterial();
 				materialPlane.colorNode = texture( createDataTexture() ).add( color( 0x0000FF ) );
 				materialPlane.colorNode = texture( createDataTexture() ).add( color( 0x0000FF ) );
-				materialPlane.opacityNode = texture( dxt5Texture ).a;
 				materialPlane.transparent = true;
 				materialPlane.transparent = true;
 
 
 				const plane = new THREE.Mesh( geometryPlane, materialPlane );
 				const plane = new THREE.Mesh( geometryPlane, materialPlane );
@@ -124,14 +133,15 @@
 				// compressed texture
 				// compressed texture
 
 
 				const materialCompressed = new MeshBasicNodeMaterial();
 				const materialCompressed = new MeshBasicNodeMaterial();
-				materialCompressed.colorNode = texture( dxt5Texture );
+				materialCompressed.colorNode = texture( ktxTexture );
 				materialCompressed.emissiveNode = oscSine().mix( color( 0x663300 ), color( 0x0000FF ) );
 				materialCompressed.emissiveNode = oscSine().mix( color( 0x663300 ), color( 0x0000FF ) );
 				materialCompressed.alphaTestNode = oscSine();
 				materialCompressed.alphaTestNode = oscSine();
 				materialCompressed.transparent = true;
 				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
 				// points
 
 
@@ -171,14 +181,6 @@
 				line.position.set( 2, 1, 0 );
 				line.position.set( 2, 1, 0 );
 				scene.add( line );
 				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 );
 				window.addEventListener( 'resize', onWindowResize );
 
 
 			}
 			}
@@ -194,8 +196,12 @@
 
 
 			function animate() {
 			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 );
 				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;
+
+			}
+
 		</script>
 		</script>
 	</body>
 	</body>
 </html>
 </html>