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

Merge pull request #20588 from Mcgode/gtlf-exporter-data-texture

DataTexture support for GLTFExporter
Mr.doob 4 лет назад
Родитель
Сommit
66e4d925e8

+ 30 - 1
examples/js/exporters/GLTFExporter.js

@@ -1,6 +1,7 @@
 //------------------------------------------------------------------------------
 // Constants
 //------------------------------------------------------------------------------
+
 var WEBGL_CONSTANTS = {
 	POINTS: 0x0000,
 	LINES: 0x0001,
@@ -776,7 +777,35 @@ THREE.GLTFExporter.prototype = {
 
 				}
 
-				ctx.drawImage( image, 0, 0, canvas.width, canvas.height );
+				if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
+					( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
+					( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
+
+					ctx.drawImage( image, 0, 0, canvas.width, canvas.height );
+
+				} else {
+
+					if ( format !== THREE.RGBAFormat && format !== THREE.RGBFormat )
+						throw "Only RGB and RGBA formats are supported";
+
+					if ( image.width !== canvas.width || image.height !== canvas.height )
+						console.warn( "Image size and imposed canvas sized do not match" );
+
+					let data = image.data;
+					if ( format === THREE.RGBFormat ) {
+
+						data = new Uint8ClampedArray( image.height * image.width * 4 );
+						data.forEach( function ( _, i ) {
+
+							data[ i ] = i % 4 === 3 ? 255 : image.data[ 3 * Math.floor( i / 4 ) + i % 4 ];
+
+						} );
+
+					}
+
+					ctx.putImageData( new ImageData( data, image.width, image.height ), 0, 0 );
+
+				}
 
 				if ( options.binary === true ) {
 

+ 31 - 2
examples/jsm/exporters/GLTFExporter.js

@@ -14,8 +14,9 @@ import {
 	NearestMipmapLinearFilter,
 	NearestMipmapNearestFilter,
 	PropertyBinding,
-	RGBAFormat,
 	RepeatWrapping,
+	RGBAFormat,
+	RGBFormat,
 	Scene,
 	Vector3
 } from "../../../build/three.module.js";
@@ -798,7 +799,35 @@ GLTFExporter.prototype = {
 
 				}
 
-				ctx.drawImage( image, 0, 0, canvas.width, canvas.height );
+				if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
+					( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
+					( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
+
+					ctx.drawImage( image, 0, 0, canvas.width, canvas.height );
+
+				} else {
+
+					if ( format !== RGBAFormat && format !== RGBFormat )
+						throw "Only RGB and RGBA formats are supported";
+
+					if ( image.width !== canvas.width || image.height !== canvas.height )
+						console.warn( "Image size and imposed canvas sized do not match" );
+
+					let data = image.data;
+					if ( format === RGBFormat ) {
+
+						data = new Uint8ClampedArray( image.height * image.width * 4 );
+						data.forEach( function ( _, i ) {
+
+							data[ i ] = i % 4 === 3 ? 255 : image.data[ 3 * Math.floor( i / 4 ) + i % 4 ];
+
+						} );
+
+					}
+
+					ctx.putImageData( new ImageData( data, image.width, image.height ), 0, 0 );
+
+				}
 
 				if ( options.binary === true ) {
 

+ 18 - 0
examples/misc_exporter_gltf.html

@@ -138,6 +138,23 @@
 				container = document.createElement( 'div' );
 				document.body.appendChild( container );
 
+				// Make linear gradient texture
+				const data = new Uint8ClampedArray( 100 * 100 * 3 );
+				for ( let y = 0; y < 100; y ++ ) {
+
+					for ( let x = 0; x < 100; x ++ ) {
+
+						data[ 3 * ( 100 * y + x ) ] = Math.round( 255 * y / 99 );
+						data[ 3 * ( 100 * y + x ) + 1 ] = Math.round( 255 - 255 * y / 99 );
+
+					}
+
+				}
+
+				const gradientTexture = new THREE.DataTexture( data, 100, 100, THREE.RGBFormat );
+				gradientTexture.minFilter = THREE.LinearFilter;
+				gradientTexture.magFilter = THREE.LinearFilter;
+
 				scene1 = new THREE.Scene();
 				scene1.name = 'Scene1';
 
@@ -230,6 +247,7 @@
 					roughness: 1.0,
 					flatShading: true
 				} );
+				material.map = gradientTexture;
 				sphere = new THREE.Mesh( new THREE.SphereBufferGeometry( 70, 10, 10 ), material );
 				sphere.position.set( 0, 0, 0 );
 				sphere.name = "Sphere";