javascript – 在运行时在3.js中更改加载的.obj的纹理

前端之家收集整理的这篇文章主要介绍了javascript – 在运行时在3.js中更改加载的.obj的纹理前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试在运行时交换一个加载的3.js .obj的图像纹理.以下是来自three.js示例的代码,稍作修改
var container,stats;
        var camera,scene,renderer;
        var mouseX = 0,mouseY = 0;
        var windowHalfX = window.innerWidth / 2;
        var windowHalfY = window.innerHeight / 2;


        init();
        animate();


        function init() {

            container = document.createElement( 'div' );
            document.body.appendChild( container );

            camera = new THREE.PerspectiveCamera( 45,window.innerWidth / window.innerHeight,1,2000 );
            camera.position.z = 100;

            //scene
            scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight( 0x101030 );
            scene.add( ambient );

            var directionalLight = new THREE.DirectionalLight( 0xfFeedd );
            directionalLight.position.set( 0,1 );
            scene.add( directionalLight );

            //manager
            var manager = new THREE.LoadingManager();
            manager.onProgress = function ( item,loaded,total ) {

                console.log( item,total );

            };

            //model
            var loader = new THREE.OBJLoader( manager );
            loader.load( 'obj/female02/female02.obj',function ( object ) {
                object.traverse( function ( child ) {

                    if ( child instanceof THREE.Mesh ) {
                        //create a global var to reference later when changing textures
                        myMesh = child;
                        //apply texture
                        myMesh.material.map = THREE.ImageUtils.loadTexture( 'textures/ash_uvgrid01.jpg');
                        myMesh.material.needsUpdate = true;
                    }

                } );


                object.position.y = - 80;
                scene.add( object );

            } );

            //render
            renderer = new THREE.WebGLRenderer();
            renderer.setSize( window.innerWidth,window.innerHeight );
            container.appendChild( renderer.domElement );

            document.addEventListener( 'mousemove',onDocumentMouseMove,false );
            window.addEventListener( 'resize',onWindowResize,false );

        }

        function newTexture() {
            myMesh.material.map = THREE.ImageUtils.loadTexture( 'textures/land_ocean_ice_cloud_2048.jpg');
            myMesh.material.needsUpdate = true;
        }

        function onWindowResize() {

            windowHalfX = window.innerWidth / 2;
            windowHalfY = window.innerHeight / 2;

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize( window.innerWidth,window.innerHeight );

        }

        function onDocumentMouseMove( event ) {

            mouseX = ( event.clientX - windowHalfX ) / 2;
            mouseY = ( event.clientY - windowHalfY ) / 2;

        }

        //animate
        function animate() {

            requestAnimationFrame( animate );
            render();

        }

        function render() {

            camera.position.x += ( mouseX - camera.position.x ) * .05;
            camera.position.y += ( - mouseY - camera.position.y ) * .05;

            camera.lookAt( scene.position );

            renderer.render( scene,camera );

        }

添加的唯一的东西是newTexture函数和网格的引用作为myMesh.这是原始的例子(http://threejs.org/examples/webgl_loader_obj.html).该函数不会抛出任何错误,但是.obj不会更新.我知道我只是在这里错过了一些基本的东西.

更新:根据下面的优秀答案,以下是正确的代码,通过输入字段交换纹理的一些补充:

var container,stats;
  var camera,renderer;
  var mouseX = 0,mouseY = 0;
  var windowHalfX = window.innerWidth / 2;
  var windowHalfY = window.innerHeight / 2;
  var globalObject;

  init();
  animate();

  function init() {
      container = document.createElement('div');
      document.body.appendChild(container);

      camera = new THREE.PerspectiveCamera(45,2000);
      camera.position.z = 100;

      //scene
      scene = new THREE.Scene();

      var ambient = new THREE.AmbientLight( 0x101030 );
      scene.add( ambient );

      var directionalLight = new THREE.DirectionalLight( 0xfFeedd );
      directionalLight.position.set( 0,1 );
      scene.add( directionalLight );

      //manager
      var manager = new THREE.LoadingManager();
      manager.onProgress = function (item,total) {
        console.log( item,total );
      };

    //model
    var loader = new THREE.OBJLoader( manager );
    loader.load( 'obj/female02/female02.obj',function (object) {
        //store global reference to .obj
        globalObject = object;

      object.traverse( function (child) {
          if ( child instanceof THREE.Mesh ) {
              child.material.map = THREE.ImageUtils.loadTexture( 'textures/grid.jpg');
              child.material.needsUpdate = true;
          }
      });

      object.position.y = - 80;
      scene.add( object );
    });

    //render
    renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth,window.innerHeight );
    container.appendChild( renderer.domElement );

    document.addEventListener( 'mousemove',false );
    window.addEventListener( 'resize',false );
  }

  function onWindowResize() {
    windowHalfX = window.innerWidth / 2;
    windowHalfY = window.innerHeight / 2;
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize( window.innerWidth,window.innerHeight );
  }

  function onDocumentMouseMove( event ) {
    mouseX = ( event.clientX - windowHalfX ) / 2;
    mouseY = ( event.clientY - windowHalfY ) / 2;
  }

  //animate
  function animate() {
    requestAnimationFrame( animate );
    render();
  }

  function render() {
    camera.position.x += ( mouseX - camera.position.x ) * .05;
    camera.position.y += ( - mouseY - camera.position.y ) * .05;
            camera.lookAt( scene.position );
            renderer.render( scene,camera );
  }

  function newTexture() {
    var newTexturePath = "textures/" + document.getElementById("texture").value + "";

    globalObject.traverse( function ( child ) {
      if (child instanceof THREE.Mesh) {
          //create a global var to reference later when changing textures
          child;
          //apply texture
          child.material.map = THREE.ImageUtils.loadTexture(newTexturePath);
          child.material.needsUpdate = true;
      }
    });
  }

解决方法

这里的问题是对象变量中有多个子网格.通过只有一个myMesh全局变量,您只存储最后一个子网格.因此,当您尝试使用此全局变量更新纹理时,只有一个网格获得纹理更新,可能是一个不清楚可见的小隐藏部分.

解决方案是:

>存储myMeshes数组全局变量,并将myMesh推送到每个变量中.然后在您的newTexture()函数中,遍历该数组中的所有项目并更新其地图/材料.
>或者,将对象变量(从OBJLoader的回调返回的变量)存储到一个单一的全局变量中.然后在你的newTexture()函数中,遍历所有的网格,就像在代码中使用(使用遍历()和if语句)一样,并更新他们的地图/材质.

最后,在你的代码调用newTexture()也可以帮助;)

原文链接:https://www.f2er.com/js/155079.html

猜你在找的JavaScript相关文章