Sergio Solorzano
Sergio Solorzano

Reputation: 665

Error referencing same basis texture files with Promise in Three.js

I am using example https://threejs.org/examples/#webgl_materials_standard for my purposes but can't get the code to read both metal and rough maps when using promise (Cerberus_RM metalness is in channel B roughness is in channel G):

Promise.all([
                    new Promise((resolve, reject) => basisLoader.load( 
    "Photog_Glace1/Cerberus_A.basis", resolve, undefined, reject ) ),
                    new Promise((resolve, reject) => basisLoader.load( 
    "Photog_Glace1/Cerberus_N.basis", resolve, undefined, reject ) ),
                    **new Promise((resolve, reject) => basisLoader.load( 
    "Photog_Glace1/Cerberus_RM.basis", resolve, undefined, reject ) ),**
**                  new Promise((resolve, reject) => basisLoader.load( 
    "Photog_Glace1/Cerberus_RM.basis", resolve, undefined, reject ) ),**
**                  ]).then(([albedoM, normalMap, metalMap, roughMap]) => {**

Yields error:

BasisTextureLoader.js:152 Uncaught (in promise) DOMException: Failed to execute 'postMessage' on 'Worker': ArrayBuffer at index 0 is already neutered. at examples/jsm/loaders/BasisTextureLoader.js:152:13 at new Promise (<anonymous>) at examples/jsm/loaders/BasisTextureLoader.js:146:12

I tried this code but I only get a full metal textured object without roughness (both roughness and metalness settings=1). Can I please get some guidance how to build this with Promise

Promise.all([
                new Promise((resolve, reject) => basisLoader.load( "Photog_Glace1/Cerberus_A.basis", resolve, undefined, reject ) ),
                new Promise((resolve, reject) => basisLoader.load( "Photog_Glace1/Cerberus_N.basis", resolve, undefined, reject ) ),
                new Promise((resolve, reject) => basisLoader.load(Photog_Glace1/Cerberus_RM.basis", resolve, undefined, reject ) ),
            ]).then(([albedoM, normalMap, metalMap, roughMap]) => {
            albedoM.encoding = THREE.sRGBEncoding;
                                albedoM.wrapS = THREE.RepeatWrapping;
                                albedoM.wrapT = THREE.RepeatWrapping;
            albedoM.repeat.x = 1;
                                albedoM.repeat.y = 1;

            normalMap.wrapS = THREE.RepeatWrapping;
                                normalMap.wrapT = THREE.RepeatWrapping;
                                normalMap.repeat.x = 1;
                                normalMap.repeat.y = 1;

            metalMap.wrapS = THREE.RepeatWrapping;
                                metalMap.wrapT = THREE.RepeatWrapping;
                                metalMap.repeat.x = 1;
                                metalMap.repeat.y = 1;
            roughMap=metalMap;

             vaseMeshMaterial = new THREE.MeshStandardMaterial({
                    roughnessMap: roughMap,
                    metalnessMap: metalMap,
                    map: albedoM,
                    normalMap: normalMap,
                    roughness: settings.roughness,
                    metalness: settings.metalness,
                    side: THREE.DoubleSide
                    });

                    roughMap.wrapS = THREE.RepeatWrapping;
                    roughMap.wrapT = THREE.RepeatWrapping;
                    roughMap.repeat.x = 1;
                    roughMap.repeat.y = 1;

in case three.js forum would become unavailable solution was:

Promise.all([
					new Promise((resolve, reject) => basisLoader.load( "Photog_Glace1/albedo.basis", resolve, undefined, reject ) ),
					new Promise((resolve, reject) => basisLoader.load( "Photog_Glace1/normal.basis", resolve, undefined, reject ) ),
					new Promise((resolve, reject) => basisLoader.load( "Photog_Glace1/cavity.basis", resolve, undefined, reject ) ),
					new Promise((resolve, reject) => basisLoader.load( "Photog_Glace1/rough_metal_Map.basis", resolve, undefined, reject ) ),
						]).then(([albedoM, normalMap, aoMap, metalRoughMap]) => {

					albedoM.encoding = THREE.sRGBEncoding;
				   
					vaseMeshMaterial = new THREE.MeshStandardMaterial({
						roughnessMap: metalRoughMap,
						metalnessMap: metalRoughMap,
						map: albedoM,
						normalMap: normalMap,
						roughness: settings.roughness,
						metalness: settings.metalness,
						aoMap: aoMap,
						aoMapIntensity: 1,
						flatShading: false,
					
						side: THREE.DoubleSide
					});
					
    				console.log("Materials Finished Loading");
					myObjectLoader.load( "Photog_Glace1/Glace1_Model.obj", function ( group ) {
						var geometry = group.children[ 0 ].geometry;
						geometry.attributes.uv2 = geometry.attributes.uv;
						geometry.center();

						vaseMesh = new THREE.Mesh( geometry, vaseMeshMaterial );
						vaseMeshMaterial.normalScale.x = -1;
						vaseMesh.castShadow = true;
						vaseMesh.receiveShadow = true;
						vaseMesh.position.set(28,0,0);
					} , onProgress,onError);
				});

Upvotes: 0

Views: 74

Answers (1)

Sergio Solorzano
Sergio Solorzano

Reputation: 665

The problem was basis loader won't read the same file more than once, e.g. metallic in B channel and rough in G channel. I couldn't get the right code using Promise. Thanks to @Mugen87 and @donmccurdy who helped solved the issue, full thread on Three.js forum https://discourse.threejs.org/t/how-part-rough-part-specular/9985/8

Upvotes: 2

Related Questions