首页 文章

如何动态叠加GLTF模型的纹理 - Three.js

提问于
浏览
2

我想从GLTF模型覆盖/打开和关闭纹理,但无法找到如何或是否可能 . 我能够完美地加载它,但当我尝试重新加载或覆盖纹理没有任何反应或我得到一些错误 . 我尝试的最后一件事并没有给我任何错误,但模型保留了原始纹理 . 我也尝试卸载模型并重新加载其他纹理,也没有成功 .

我正在使用来自three.js文档的标准THREE.GLTFLoader示例,只是更改了3d加载模型并添加了一段时间后执行此更改的函数 . 我可能会混淆一切,如果你能帮助我会很感激,谢谢你提前 .

访问过的链接对我没有帮助:ThreeJS: Remove object from scene; three.js Switching objects on click; How do I change the texture of a GLTF model dynamically?; Change texture of loaded .obj in three.js at runtime; Import another Texture at runtime within THREE.JS and GLTF

我正在使用的代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>three.js webgl - glTF loader</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            font-family: Monospace;
            background-color: #000;
            color: #fff;
            margin: 0px;
            overflow: hidden;
        }
        #info {
            color: #fff;
            position: absolute;
            top: 10px;
            width: 100%;
            text-align: center;
            z-index: 100;
            display:block;
        }
        #info a {
            color: #75ddc1;
            font-weight: bold;
        }
    </style>
</head>

<body>
    <div id="info"><!--
        <a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - GLTFLoader
Battle Damaged Sci-fi Helmet by <a href="https://sketchfab.com/theblueturtle_" target="_blank" rel="noopener">theblueturtle_</a>
--> </div> <script src="build/three.js"></script> <script src="js/controls/OrbitControls.js"></script> <script src="js/loaders/GLTFLoader.js"></script> <script src="js/Detector.js"></script> <script src="js/libs/stats.min.js"></script> <script> if ( ! Detector.webgl ) Detector.addGetWebGLMessage(); var container, stats, controls; var camera, scene, renderer, light; var globalObject; init(); animate(); function init() { container = document.createElement( 'div' ); document.body.appendChild( container ); camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 2000 ); camera.position.set( -250.8, 260.9, 262.7 ); controls = new THREE.OrbitControls( camera ); controls.target.set( 0, -0.2, -0.2 ); controls.update(); // envmap var path = 'textures/cube/Bridge2/'; var format = '.jpg'; var envMap = new THREE.CubeTextureLoader().load( [ path + 'posx' + format, path + 'negx' + format, path + 'posy' + format, path + 'negy' + format, path + 'posz' + format, path + 'negz' + format ] ); scene = new THREE.Scene(); scene.background = envMap; light = new THREE.HemisphereLight( 0xbbbbff, 0x444422 ); light.position.set( 0, 1, 0 ); scene.add( light ); // model var loader = new THREE.GLTFLoader(); loader.load( 'models/testeFinal2-1/testeFinal2-1.gltf', function ( gltf ) { globalObject = gltf.scene; gltf.scene.traverse( function ( child ) { if ( child.isMesh ) { child.material.envMap = envMap; } } ); scene.add( gltf.scene ); } ); renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.gammaOutput = true; container.appendChild( renderer.domElement ); window.addEventListener( 'resize', onWindowResize, false ); // stats stats = new Stats(); container.appendChild( stats.dom ); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } // function animate() { requestAnimationFrame( animate ); renderer.render( scene, camera ); stats.update(); } setTimeout(newTexture(), 7000); //Do the changes after 7s. function newTexture() { scene.remove( globalObject ); //This don't give me any error, but does nothing. // envmap var path = 'textures/cube/Bridge2/'; var format = '.jpg'; var envMap = new THREE.CubeTextureLoader().load( [ path + 'posx' + format, path + 'negx' + format, path + 'posy' + format, path + 'negy' + format, path + 'posz' + format, path + 'negz' + format ] ); var loader = new THREE.GLTFLoader(); //Trying to reload the second time, does nothing either. loader.load( 'models/testeFinal2-1/2/testeFinal2-1.gltf', function ( gltf ) { gltf.scene.traverse( function ( child ) { if ( child.isMesh ) { child.material.envMap = envMap; } } ); scene.add( gltf.scene ); } ); } </script> </body>

UPDATE1(删除了newTexture函数并编辑了模型的加载器):

// model
            var loader = new THREE.GLTFLoader();
            loader.load( 'models/testeFinal2-1/testeFinal2-1.gltf', function ( gltf ) {

                globalObject = gltf.scene;

                gltf.scene.traverse( function ( child ) {

                    if ( child.isMesh ) {

                        child.material.envMap = envMap;

                        setTimeout(function () {
                            child.material.map.image.currentSrc = "/models/testeFinal2-1/2/finalTest2_ORTO2.jpg";
                            child.material.map.image.src = "/models/testeFinal2-1/2/finalTest2_ORTO2.jpg";
                        }, 5000);

                    }

                } );

                scene.add( gltf.scene );

            } );

1 回答

  • 0

    加载模型后,可以使用THREE.TextureLoader将新纹理附加到模型 . 执行此操作时,请务必设置 texture.flipY=false 以匹配glTF模型的UV方向 .

    var textureLoader = new THREE.TextureLoader();
    var texture = textureLoader.load( 'foo.png' );
    texture.flipY = false;
    
    var loader = new THREE.GLTFLoader();
    loader.load( 'foo.glb', ( gltf ) => {
      var model = gltf.scene;
      model.traverse ( ( o ) => {
        if ( o.isMesh ) {
          // note: for a multi-material mesh, `o.material` may be an array,
          // in which case you'd need to set `.map` on each value.
          o.material.map = texture;
        }
      } );
      scene.add( model );
    } );
    

相关问题