Просмотр исходного кода

Add 24bit uncompressed RGB support to DDSLoader (#30010)

* Add 24bit uncompressed RGB support to DDSLoader

Adds support for 24bit uncompressed RGB textured to DDSLoader.
The texture data is read from the file in RGB, and returned in RGBA format with a=1.

* Remove typescript types

* Add new example for 24bit uncompressed dds

* revert accidental package-lock.json changes

* revert accidental package-lock.json changes

* hopefully properly fix package-lock.json

* updated screenshots for webgl_loader_texture_dds

* Update DDSLoader.js

Clean up.

---------

Co-authored-by: Michael Herzog <michael.herzog@human-interactive.org>
Samuel 1 год назад
Родитель
Сommit
45b953d0d3

+ 42 - 0
examples/jsm/loaders/DDSLoader.js

@@ -109,6 +109,33 @@ class DDSLoader extends CompressedTextureLoader {
 
 		}
 
+		function loadRGBMip( buffer, dataOffset, width, height ) {
+
+			const dataLength = width * height * 3;
+			const srcBuffer = new Uint8Array( buffer, dataOffset, dataLength );
+			const byteArray = new Uint8Array( width * height * 4 );
+			let dst = 0;
+			let src = 0;
+			for ( let y = 0; y < height; y ++ ) {
+
+				for ( let x = 0; x < width; x ++ ) {
+
+					const b = srcBuffer[ src ]; src ++;
+					const g = srcBuffer[ src ]; src ++;
+					const r = srcBuffer[ src ]; src ++;
+					byteArray[ dst ] = r; dst ++;	//r
+					byteArray[ dst ] = g; dst ++;	//g
+					byteArray[ dst ] = b; dst ++;	//b
+                    			byteArray[ dst ] = 1.0; dst ++; //a
+
+				}
+
+			}
+
+			return byteArray;
+
+		}
+
 		const FOURCC_DXT1 = fourCCToInt32( 'DXT1' );
 		const FOURCC_DXT3 = fourCCToInt32( 'DXT3' );
 		const FOURCC_DXT5 = fourCCToInt32( 'DXT5' );
@@ -161,6 +188,7 @@ class DDSLoader extends CompressedTextureLoader {
 		const fourCC = header[ off_pfFourCC ];
 
 		let isRGBAUncompressed = false;
+		let isRGBUncompressed = false;
 
 		let dataOffset = header[ off_size ] + 4;
 
@@ -236,6 +264,15 @@ class DDSLoader extends CompressedTextureLoader {
 					blockBytes = 64;
 					dds.format = RGBAFormat;
 
+				} else if ( header[ off_RGBBitCount ] === 24
+					&& header[ off_RBitMask ] & 0xff0000
+					&& header[ off_GBitMask ] & 0xff00
+					&& header[ off_BBitMask ] & 0xff ) {
+
+				    	isRGBUncompressed = true;
+                    			blockBytes = 64;
+                    			dds.format = RGBAFormat;
+
 				} else {
 
 					console.error( 'THREE.DDSLoader.parse: Unsupported FourCC code ', int32ToFourCC( fourCC ) );
@@ -290,6 +327,11 @@ class DDSLoader extends CompressedTextureLoader {
 					byteArray = loadARGBMip( buffer, dataOffset, width, height );
 					dataLength = byteArray.length;
 
+				} else if ( isRGBUncompressed ) {
+
+					byteArray = loadRGBMip( buffer, dataOffset, width, height );
+					dataLength = width * height * 3;
+
 				} else {
 
 					dataLength = Math.max( 4, width ) / 4 * Math.max( 4, height ) / 4 * blockBytes;

BIN
examples/screenshots/webgl_loader_texture_dds.jpg


BIN
examples/textures/wave_normals_24bit_uncompressed.dds


+ 12 - 2
examples/webgl_loader_texture_dds.html

@@ -35,8 +35,9 @@
 
 			function init() {
 
-				camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 100 );
-				camera.position.z = 15;
+				camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 100 );
+				camera.position.y = -2;
+				camera.position.z = 16;
 
 				scene = new THREE.Scene();
 
@@ -90,6 +91,8 @@
 				const map10 = loader.load( 'textures/compressed/disturb_dx10_bc6h_unsigned_mip.dds' );
 				map10.anisotropy = 4;
 
+				const map11 = loader.load( 'textures/wave_normals_24bit_uncompressed.dds' );
+				map11.anisotropy = 4;
 
 				const cubemap1 = loader.load( 'textures/compressed/Mountains.dds', function ( texture ) {
 
@@ -133,6 +136,7 @@
 				const material10 = new THREE.MeshBasicMaterial( { map: map8 } );
 				const material11 = new THREE.MeshBasicMaterial( { map: map9 } );
 				const material12 = new THREE.MeshBasicMaterial( { map: map10 } );
+				const material13 = new THREE.MeshBasicMaterial( { map: map11 } );
 
 				let mesh = new THREE.Mesh( new THREE.TorusGeometry(), material1 );
 				mesh.position.x = - 10;
@@ -206,6 +210,12 @@
 				scene.add( mesh );
 				meshes.push( mesh );
 
+				mesh = new THREE.Mesh( geometry, material13 );
+				mesh.position.x = -10;
+				mesh.position.y = -6;
+				scene.add( mesh );
+				meshes.push( mesh );
+
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );

粤ICP备19079148号