瀏覽代碼

USDZLoader: Improved texture support.

Mr.doob 2 年之前
父節點
當前提交
d190283b10
共有 3 個文件被更改,包括 109 次插入12 次删除
  1. 108 12
      examples/jsm/loaders/USDZLoader.js
  2. 二進制
      examples/screenshots/webgl_loader_usdz.jpg
  3. 1 0
      examples/webgl_loader_usdz.html

+ 108 - 12
examples/jsm/loaders/USDZLoader.js

@@ -1,12 +1,16 @@
 import {
 	BufferAttribute,
 	BufferGeometry,
+	ClampToEdgeWrapping,
 	FileLoader,
 	Group,
 	Loader,
 	Mesh,
 	MeshStandardMaterial,
-	TextureLoader
+	MirroredRepeatWrapping,
+	RepeatWrapping,
+	sRGBEncoding,
+	TextureLoader,
 } from 'three';
 
 import * as fflate from '../libs/fflate.module.js';
@@ -265,15 +269,23 @@ class USDZLoader extends Loader {
 
 					// Move points to Mesh
 
-					if ( data[ 'point3f[] points' ] ) {
+					if ( 'point3f[] points' in data ) {
 
 						object[ 'point3f[] points' ] = data[ 'point3f[] points' ];
 
 					}
 
+					// Move st to Mesh
+
+					if ( 'float2[] primvars:st' in data ) {
+
+						object[ 'float2[] primvars:st' ] = data[ 'float2[] primvars:st' ];
+
+					}
+
 					// Move st indices to Mesh
 
-					if ( data[ 'int[] primvars:st:indices' ] ) {
+					if ( 'int[] primvars:st:indices' in data ) {
 
 						object[ 'int[] primvars:st:indices' ] = data[ 'int[] primvars:st:indices' ];
 
@@ -327,6 +339,12 @@ class USDZLoader extends Loader {
 
 			}
 
+			if ( 'float2[] primvars:st' in data ) {
+
+				data[ 'texCoord2f[] primvars:st' ] = data[ 'float2[] primvars:st' ];
+
+			}
+
 			if ( 'texCoord2f[] primvars:st' in data ) {
 
 				const uvs = JSON.parse( data[ 'texCoord2f[] primvars:st' ].replace( /[()]*/g, '' ) );
@@ -426,22 +444,41 @@ class USDZLoader extends Loader {
 
 					const surface = data[ 'def Shader "PreviewSurface"' ];
 
-					if ( 'color3f inputs:diffuseColor' in surface ) {
+					if ( 'color3f inputs:diffuseColor.connect' in surface ) {
+
+						const path = surface[ 'color3f inputs:diffuseColor.connect' ];
+						const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
+
+						material.map = buildTexture( sampler );
+						material.map.encoding = sRGBEncoding;
+
+					} else if ( 'color3f inputs:diffuseColor' in surface ) {
 
 						const color = surface[ 'color3f inputs:diffuseColor' ].replace( /[()]*/g, '' );
 						material.color.fromArray( JSON.parse( '[' + color + ']' ) );
 
 					}
 
+					if ( 'normal3f inputs:normal.connect' in surface ) {
+
+						console.log( surface );
+
+						const path = surface[ 'normal3f inputs:normal.connect' ];
+						const sampler = findTexture( root, /(\w+).output/.exec( path )[ 1 ] );
+
+						material.normalMap = buildTexture( sampler );
+
+					}
+
 					if ( 'float inputs:roughness' in surface ) {
 
-						material.roughness = surface[ 'float inputs:roughness' ];
+						material.roughness = parseFloat( surface[ 'float inputs:roughness' ] );
 
 					}
 
 					if ( 'float inputs:metallic' in surface ) {
 
-						material.metalness = surface[ 'float inputs:metallic' ];
+						material.metalness = parseFloat( surface[ 'float inputs:metallic' ] );
 
 					}
 
@@ -449,19 +486,18 @@ class USDZLoader extends Loader {
 
 				if ( 'def Shader "diffuseColor_texture"' in data ) {
 
-					const texture = data[ 'def Shader "diffuseColor_texture"' ];
-					const file = texture[ 'asset inputs:file' ].replace( /@*/g, '' );
+					const sampler = data[ 'def Shader "diffuseColor_texture"' ];
 
-					material.map = new TextureLoader().load( assets[ file ] );
+					material.map = buildTexture( sampler );
+					material.map.encoding = sRGBEncoding;
 
 				}
 
 				if ( 'def Shader "normal_texture"' in data ) {
 
-					const texture = data[ 'def Shader "normal_texture"' ];
-					const file = texture[ 'asset inputs:file' ].replace( /@*/g, '' );
+					const sampler = data[ 'def Shader "normal_texture"' ];
 
-					material.normalMap = new TextureLoader().load( assets[ file ] );
+					material.normalMap = buildTexture( sampler );
 
 				}
 
@@ -471,6 +507,66 @@ class USDZLoader extends Loader {
 
 		}
 
+		function findTexture( data, id ) {
+
+			for ( const name in data ) {
+
+				const object = data[ name ];
+
+				if ( name.startsWith( `def Shader "${ id }"` ) ) {
+
+					return object;
+
+				}
+
+				if ( typeof object === 'object' ) {
+
+					const texture = findTexture( object, id );
+
+					if ( texture ) return texture;
+
+				}
+
+			}			
+
+		}
+
+		function buildTexture( data ) {
+
+			if ( 'asset inputs:file' in data ) {
+
+				const path = data[ 'asset inputs:file' ].replace( /@*/g, '' );
+
+				const loader = new TextureLoader();
+
+				const texture = loader.load( assets[ path ] );
+
+				const map = {
+					'"clamp"': ClampToEdgeWrapping,
+					'"mirror"': MirroredRepeatWrapping,
+					'"repeat"': RepeatWrapping
+				};
+
+				if ( 'token inputs:wrapS' in data ) {
+
+					texture.wrapS = map[ data[ 'token inputs:wrapS' ] ];
+
+				}
+
+				if ( 'token inputs:wrapT' in data ) {
+
+					texture.wrapT = map[ data[ 'token inputs:wrapT' ] ];
+
+				}
+
+				return texture;
+
+			}
+
+			return null;
+
+		}
+
 		function buildMesh( data ) {
 
 			const geometry = buildGeometry( findMeshGeometry( data ) );

二進制
examples/screenshots/webgl_loader_usdz.jpg


+ 1 - 0
examples/webgl_loader_usdz.html

@@ -66,6 +66,7 @@
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.outputEncoding = THREE.sRGBEncoding;
 				document.body.appendChild( renderer.domElement );
 
 				controls = new OrbitControls( camera, renderer.domElement );