How to change the color for two GLTF objects at the same time?

Hello to all. It is possible to change the color of objects (or parts of objects) loaded in the format gltf. Below is my code. It works. I have two objects GLTF (actually there are more) with the prescribed “KHR_materials_variants”. I add a cube camera to each object and assign a “envMap = cubeRenderTarget” to each object. A GUI panel has been added to each object. The colors of both objects can be switched in one panel. How do I hide the second panel (gui29)? Or redo the code so that there is only one panel?

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>salunMagia1</title>
		<linc rel="stylesheet" href="css/styles.css">		
		</head>			
	    <canvas id="sal6"></canvas>	    
	    <div id="stats"></div>	    
	    <div id="container"></div>	    
		<div id = "cursor" style="cursor:crosshair">	    
	    </div>	    
	    <div id="blocker">
        <div id="instructions">        
        </div>
        </div>
	<body>

		<!--<script type="module" src='bundle1-utf8.js'>-->
	   <script type="module">


import * as THREE from '../build/three.module.js';
import Stats from './jsm/libs/stats.module.js';

			import { OrbitControls } from './jsm/controls/OrbitControls.js';
			import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
  			import { PointerLockControls } from './jsm/controls/PointerLockControls.js';
			import { TrackballControls } from './jsm/controls/TrackballControls.js';
			import { FirstPersonControls } from './jsm/controls/FirstPersonControls.js';
			import { GUI } from './jsm/libs/dat.gui.module.js';
    var scene, camera, mesh;
    var camControls;
    var clock;	
	clock = new THREE.Clock();	    
  	var width = window.innerWidth;
	var height = window.innerHeight;	
	var canvas = document.getElementById('sal6');
	var blocker = document.getElementById('blocker');
	var statsNode = document.getElementById('stats');
	  canvas.setAttribute('width', width);
	  canvas.setAttribute('height', height);
	  
	  		scene = new THREE.Scene();
				
	    var renderer = new THREE.WebGLRenderer({canvas: canvas, antialias:true,alpha:true,transparent:true,premultipliedAlpha:false});
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setClearColor(0xffffff);
        renderer.shadowMap.enabled = true;
        renderer.shadowMap.type = THREE.BasicShadowMap;
        renderer.gammaInput = true;
        renderer.gammaOutput = true;
        
        camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
		camera.position.set(0, 10, 15);
		var maxanisotropy=renderer.capabilities.getMaxAnisotropy();
				const color = 0xFFFFFF;
	const intensity = 1;
	const light = new THREE.DirectionalLight(color, intensity);
	light.position.set(2, 0.35, 0);
	light.target.position.set(0, -0.2, 0);
	scene.add(light,light.target);
	light.target.updateMatrixWorld();
	
					var loaderMatFloo = new THREE.TextureLoader();
		loaderMatFloo.crossOrigin = "use-credentials";
		var textureFloo = loaderMatFloo.load('js/textures/parket.jpg');
		textureFloo.wrapS = THREE.MirroredRepeatWrapping;
		textureFloo.wrapT = THREE.MirroredRepeatWrapping;
		var timesToRepeatHorizontally = 4;
		var timesToRepeatVertically = 4;

		textureFloo.repeat.set(timesToRepeatHorizontally, timesToRepeatVertically);
		textureFloo.anisotropy = maxanisotropy;
		var materialFloo = new THREE.MeshBasicMaterial({map: textureFloo,});
		var meshFloor = new THREE.Mesh(
	    new THREE.PlaneGeometry(20,20,1,1),
	    materialFloo);
		meshFloor.rotation.x -= Math.PI / 2;		
		meshFloor.position.y = 0;
		meshFloor.receiveShadow = true;
		meshFloor.name = "floo";
		scene.add(meshFloor);
		
		camControls = new OrbitControls(camera, renderer.domElement );
	    camControls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
		camControls.dampingFactor = 0.25;
		camControls.screenSpacePanning = false;
		camControls.minDistance = 0.2;
		camControls.maxDistance = 1;
		camControls.maxPolarAngle = Math.PI;
		camControls.minPolarAngle = -Math.PI/4;
		camControls.keyPanSpeed  = 1;
		camControls.rotateSpeed = 0.05;
		
			var gui;
			var gui29;			
			gui = new GUI();
			gui29 = new GUI();
								
				const cubeRenderTarget2 = new THREE.WebGLCubeRenderTarget(512, {
		        format: THREE.RGBFormat,
		        generateMipmaps: true,
		        minFilter: THREE.LinearMipmapLinearFilter,
		        encoding: THREE.sRGBEncoding
			    });
				 const cubeCamera2 = new THREE.CubeCamera(0.1,1000,cubeRenderTarget2
				);
			//------------object1-----------					
	var Door30 = new GLTFLoader();					
	    Door30.load('gltfmodels/door27_r2.gltf', function(ball2){
		ball2.scene;
				var door30Bbox = new THREE.Box3();
				door30Bbox.setFromObject(ball2.scene);
				var bboxDoor30Center = door30Bbox.getCenter().clone();
				bboxDoor30Center.multiplyScalar(-1);				
					ball2.scene.traverse(function(child){
						if (child.isMesh) {
                   			child.material.envMap = cubeRenderTarget2.texture;
                		}
	              			child.castShadow = true;
    						child.receiveShadow = true;							
						if (child instanceof THREE.Mesh){
							child.geometry.translate(bboxDoor30Center.x, bboxDoor30Center.y, bboxDoor30Center.z); ;
	              		}                               
					});
				door30Bbox.setFromObject(ball2.scene);
		//------------------------------------------------				
				scene.add(ball2.scene);
	
				ball2.scene.variant = 'Alum';
							const parser = ball2.parser;
							const variantsExtension = ball2.userData.gltfExtensions[ 'KHR_materials_variants' ];
							const variants = variantsExtension.variants.map( ( variant ) => variant.name );
							const variantsCtrl = gui.add( ball2.scene, 'variant', variants ).name( 'Fasad Colour' );

							selectVariant( scene, parser, variantsExtension, ball2.scene.variant  );

							variantsCtrl.onChange( ( value ) => selectVariant( scene, parser, variantsExtension, value ) );
				ball2.scene.position.set(+0.5, 0.5, -1);
				ball2.scene.rotation.y = Math.PI/2;
				cubeCamera2.position.copy( ball2.scene.position );
				render();
		});	
				
				function selectVariant( scene, parser, extension, variantName ) {

				const variantIndex = extension.variants.findIndex( ( v ) => v.name.includes( variantName ) );

				scene.traverse( async ( objectgui ) => {	
					if ( ! objectgui.isMesh || ! objectgui.userData.gltfExtensions ) return;
					const meshVariantDef = objectgui.userData.gltfExtensions[ 'KHR_materials_variants' ];
					if ( ! meshVariantDef ) return;
					if ( ! objectgui.userData.originalMaterial ) {
						objectgui.userData.originalMaterial = objectgui.material;
					}
					const mapping = meshVariantDef.mappings
						.find( ( mapping ) => mapping.variants.includes( variantIndex ) );
					if ( mapping ) {
						objectgui.material = await parser.getDependency( 'material', mapping.material );
						parser.assignFinalMaterial(objectgui);
					} else {
						objectgui.material = objectgui.userData.originalMaterial;
					}
					 if (objectgui.isMesh) { 	                  
                   objectgui.material.envMap = cubeRenderTarget2.texture;
                	}
					render();
				} );
			}
						
			const cubeRenderTarget3 = new THREE.WebGLCubeRenderTarget(512, {
		        format: THREE.RGBFormat,
		        generateMipmaps: true,
		        minFilter: THREE.LinearMipmapLinearFilter,
		        encoding: THREE.sRGBEncoding
			});
			const cubeCamera3 = new THREE.CubeCamera(0.1,1000,cubeRenderTarget3
			);
                     //------------object2-----------				
				var Door29 = new GLTFLoader();					
				    Door29.load('gltfmodels/door29.gltf', function(ball29){
					ball29.scene;

				var door29Bbox = new THREE.Box3();
					door29Bbox.setFromObject(ball29.scene);
				var bboxDoor29Center = door29Bbox.getCenter().clone();
					bboxDoor29Center.multiplyScalar(-1);				
						ball29.scene.traverse(function(child){
							if (child.isMesh) {
	                   			child.material.envMap = cubeRenderTarget3.texture;
	                		}
		              			child.castShadow = true;
	    						child.receiveShadow = true;							
							if (child instanceof THREE.Mesh){
								child.geometry.translate(bboxDoor29Center.x, bboxDoor29Center.y, bboxDoor29Center.z); ;
		              		}                               
						});
				door29Bbox.setFromObject(ball29.scene);
		//------------------------------------------------				
				scene.add(ball29.scene);	
				ball29.scene.variant = 'Alum';
							const parser = ball29.parser;
							const variantsExtension = ball29.userData.gltfExtensions[ 'KHR_materials_variants' ];
							const variants = variantsExtension.variants.map( ( variant ) => variant.name );
							const variantsCtrl = gui29.add( ball29.scene, 'variant', variants ).name( 'Fasad Colour' );

							selectVariant29( scene, parser, variantsExtension, ball29.scene.variant  );

							variantsCtrl.onChange( ( value ) => selectVariant( scene, parser, variantsExtension, value ) );
							
				ball29.scene.position.set(-0.5, 0.5, -1);
				cubeCamera3.position.copy( ball29.scene.position );
				render();
		});
		
		function selectVariant29( scene, parser, extension, variantName ) {

				const variantIndex = extension.variants.findIndex( ( v ) => v.name.includes( variantName ) );

				scene.traverse( async ( objectgui ) => {
					if ( ! objectgui.isMesh || ! objectgui.userData.gltfExtensions ) return;
					const meshVariantDef = objectgui.userData.gltfExtensions[ 'KHR_materials_variants' ];
					if ( ! meshVariantDef ) return;
					if ( ! objectgui.userData.originalMaterial ) {
						objectgui.userData.originalMaterial = objectgui.material;
					}
					const mapping = meshVariantDef.mappings
						.find( ( mapping ) => mapping.variants.includes( variantIndex ) );
					if ( mapping ) {
						objectgui.material = await parser.getDependency( 'material', mapping.material );
						parser.assignFinalMaterial(objectgui);
					} else {
						objectgui.material = objectgui.userData.originalMaterial;
					}
					 if (objectgui.isMesh) { 	                  
                   objectgui.material.envMap = cubeRenderTarget3.texture;
                	}
					render();
				} );
			}
			
	function animate() {			
		requestAnimationFrame(animate);		
		var delta = clock.getDelta();
  		camControls.update(delta);
  		cubeCamera3.update( renderer, scene );
  		cubeCamera2.update( renderer, scene );		
		render()		
	}
			function render() {
				renderer.render( scene, camera );
			}	   
		animate();		
	   		</script>
</body>
</html>

You seem to be using three.js. It might be better to ask this question on the three.js forum.

It is indicated on the Github that Kronos group are the developers of KHR_materials_variants of GLTF for Three js. I was hoping that on this forum they will be able to suggest a solution. Unfortunately, on the forum Three js I did not receive a complete answer to this question.

I’m not sure where you see that. The only person that might know here would be @donmccurdy.

Related discussion: https://discourse.threejs.org/t/how-to-change-the-color-of-two-objects-or-parts-of-them-gltf/33093

Thanks to everyone who responded to the discussion of this issue. Obviously, there is no correct solution for it at the moment. As I wrote above, the colors of all GLTF objects are changed using one GUI panel. I was able to make the GUI panels invisible for other objects by applying the following in the code:

            var gui = new GUI();
			var gui29 = new GUI({ autoPlace: false });

I understand that this is not a completely correct solution, but so far it works.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.