2013-02-07 94 views
0

我目前正在嘗試使用紋理旋轉立方體。我還希望通過使用控件(在鼠標懸停時旋轉立方體的箭頭圖像)使立方體在其x和y軸(來回)上旋轉。當它在X軸上旋轉時,立方體的背面是倒置的。three.js - 立方體背面紋理垂直翻轉

我知道這與UV貼圖的工作方式有關。所以我試圖糾正多維數據集初始化,這工作正常。但是,當我嘗試旋轉Y軸上的立方體時,紋理再次顛倒。所以我瞭解到,我必須根據旋轉請求即時更改紋理方向。

但這不適用於我。多維數據集初始化後,我發現無法更改「faceVertexUvs [0] [5]」。嘗試在初始化時爲立方體幾何設置「needsUpdate」並沒有幫助。

希望我說清楚了。有沒有解決這個問題的方法?

在此先感謝 邁克爾

爲了說明我的問題更好:我在這裏發佈我的源代碼。

它不能在JsFiddle中演示,因爲不允許使用來自其他域的紋理圖像(並且CORS不起作用)。只需複製粘貼以下代碼並將其保存爲本地「test.html」。紋理圖像可以在這裏找到:http://www.mikelmade.de/cors/t.png。它應該與「test.html」位於同一個目錄中。在支持WebGL的瀏覽器中打開「test.html」,然後將鼠標移過「向上」,你應該明白我的意思。

<html><head><script src="jquery.js"></script></head><body> 
<script src="https://raw.github.com/mrdoob/three.js/master/build/three.min.js"></script> 
<script src="https://raw.github.com/mrdoob/three.js/master/examples/js/libs/stats.min.js"> </script> 

<script> 
     var cubeGeo; 
     var materials = []; 
     var container, stats; 
     var camera, scene, renderer; 
     var cube, plane; 

     var targetRotation = 0; 
     var targetRotationOnMouseDown = 0; 

     var mouseX = 0; 
     var mouseXOnMouseDown = 0; 

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

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

      var info = document.createElement('div'); 
      info.style.position = 'absolute'; 
      info.style.top = '10px'; 
      info.style.width = '100%'; 
      info.style.textAlign = 'center'; 
      info.innerHTML = 'Drag to spin the cube'; 
      container.appendChild(info); 

      camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 1, 1000); 
      camera.position.y = 150; 
      camera.position.z = 500; 

      scene = new THREE.Scene(); 

    // add subtle ambient lighting 
    var ambientLight = new THREE.AmbientLight(0x555555); 
    scene.add(ambientLight); 

    // add directional light source 
    var directionalLight = new THREE.DirectionalLight(0xEEEEEE); 
    directionalLight.position.set(1, 1, 1).normalize(); 
    scene.add(directionalLight); 

      // Cube 
      for (var i = 0; i < 6; i ++) { 
       var img = new Image(); 
       img.src = 't.png'; 
       var tex = new THREE.Texture(img); 
       img.tex = tex; 
       img.onload = function() { this.tex.needsUpdate = true; }; 
       var mat = new THREE.MeshLambertMaterial({map: tex}); 
       materials.push(mat); 
      } 

      cubeGeo = new THREE.CubeGeometry(200,200,200,1,1,1); 
      cubeGeo.uvsNeedUpdate = true; 
      cubeGeo.dynamic = true; 

      cube = new THREE.Mesh(cubeGeo, new THREE.MeshFaceMaterial(materials)); 

      cube.position.y = 150; 
      scene.add(cube); 

      renderer = new THREE.WebGLRenderer({antialias:true}); 
      renderer.setSize(window.innerWidth, window.innerHeight); 

      // enable shadows on the renderer 
      renderer.shadowMapEnabled = true; 
      container.appendChild(renderer.domElement); 

      stats = new Stats(); 
      stats.domElement.style.position = 'absolute'; 
      stats.domElement.style.top = '0px'; 
      container.appendChild(stats.domElement); 

      document.addEventListener('mousedown', onDocumentMouseDown, false); 
      document.addEventListener('touchstart', onDocumentTouchStart, false); 
      document.addEventListener('touchmove', onDocumentTouchMove, false); 

      window.addEventListener('resize', onWindowResize, 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 onDocumentMouseDown(event) { 
      event.preventDefault(); 

      document.addEventListener('mousemove', onDocumentMouseMove, false); 
      document.addEventListener('mouseup', onDocumentMouseUp, false); 
      document.addEventListener('mouseout', onDocumentMouseOut, false); 

      mouseXOnMouseDown = event.clientX - windowHalfX; 
      targetRotationOnMouseDown = targetRotation; 
     } 

     function onDocumentMouseMove(event) { 
      mouseX = event.clientX - windowHalfX; 
      targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.02; 
     } 

     function onDocumentMouseUp(event) { 
      document.removeEventListener('mousemove', onDocumentMouseMove, false); 
      document.removeEventListener('mouseup', onDocumentMouseUp, false); 
      document.removeEventListener('mouseout', onDocumentMouseOut, false); 
     } 

     function onDocumentMouseOut(event) { 
      document.removeEventListener('mousemove', onDocumentMouseMove, false); 
      document.removeEventListener('mouseup', onDocumentMouseUp, false); 
      document.removeEventListener('mouseout', onDocumentMouseOut, false); 
     } 

     function onDocumentTouchStart(event) { 
      if (event.touches.length === 1) { 
       event.preventDefault(); 
       mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX; 
       targetRotationOnMouseDown = targetRotation; 
      } 
     } 

     function onDocumentTouchMove(event) { 
      if (event.touches.length === 1) { 
       event.preventDefault(); 
       mouseX = event.touches[ 0 ].pageX - windowHalfX; 
       targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.05; 
      } 
     } 


     function animatex(dir) { 
      cubeGeo.faceVertexUvs[0][5] = [new THREE.UV(1, 0), new THREE.UV(1, 1), new THREE.UV(0, 1), new THREE.UV(0, 0)]; 
      animate2(dir); 
     } 

     var anim = 0; 
     function animate2(dir) { 
       requestAnimationFrame(function() { 
        cubeGeo.faceVertexUvs[0][5] = [new THREE.UV(1, 0), new THREE.UV(1, 1), new THREE.UV(0, 1), new THREE.UV(0, 0)]; 
        if(anim == 1) { 
         animate2(dir); 
        } 
       }); 
       render2(); 
       stats.update(); 
     } 

     function render2() { 
      cube.rotation.x = cube.rotation.x+0.06; 
      renderer.render(scene, camera); 
     } 

     function animate() { 
      requestAnimationFrame(animate); 
      render(); 
      stats.update(); 

     } 

     function render() { 
      cube.rotation.y += (targetRotation - cube.rotation.y) * 0.05; 
      $('#test').html(cube.rotation.y); 
      renderer.render(scene, camera); 
     } 

    </script> 
    <div id="up" style="position:absolute;z-index:500000;left:100px;top:20px;" class="nav">up</div> 
    <div id="down" style="position:absolute;z-index:500000;left:100px;top:40px;" class="nav">down</div> 
    <div id="left" style="position:absolute;z-index:500000;left:100px;top:60px;" class="nav">left</div> 
    <div id="right" style="position:absolute;z-index:500000;left:100px;top:80px;" class="nav">right</div> 
    <div id="test" style="position:absolute;z-index:500000;left:100px;top:100px;"> </div> 
    <script> 
     var _interval = 0; 
     $(document).ready(function(){ 
     $('.nav').mouseover(function() { 
      switch($(this).prop('id')) { 
       case 'up': 
        anim = 1; 
        animatex('up'); 
       break; 
      } 
     }); 

     $('.nav').mouseout(
      function() { 
       anim = 0; 
      } 
     ); 
     }); 
     </script> 
    </body> 
</html> 
+0

你可以添加soome代碼片段或jsfiddle鏈接嗎? – 0xor1

回答

0

cubeGeo是一個幾何體,而不是一個網格,所以設置是。

cubeGeo.uvsNeedUpdate = true; 

而且小提琴

http://jsfiddle.net/crossphire/JebXL/2/

下面是修改的例子

<html><head> 
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> 
</head><body> 
<script src="https://raw.github.com/mrdoob/three.js/master/build/three.min.js"></script> 
<script src="https://raw.github.com/mrdoob/three.js/master/examples/js/libs/stats.min.js"> </script> 

<script> 
     var cubeGeo; 
     var materials = []; 
     var container, stats; 
     var camera, scene, renderer; 
     var cube, plane; 

     var targetRotation = 0; 
     var targetRotationOnMouseDown = 0; 

     var mouseX = 0; 
     var mouseXOnMouseDown = 0; 

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

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

      var info = document.createElement('div'); 
      info.style.position = 'absolute'; 
      info.style.top = '10px'; 
      info.style.width = '100%'; 
      info.style.textAlign = 'center'; 
      info.innerHTML = 'Drag to spin the cube'; 
      container.appendChild(info); 

      camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 1, 1000); 
      camera.position.y = 150; 
      camera.position.z = 500; 

      scene = new THREE.Scene(); 

    // add subtle ambient lighting 
    var ambientLight = new THREE.AmbientLight(0x555555); 
    scene.add(ambientLight); 

    // add directional light source 
    var directionalLight = new THREE.DirectionalLight(0xEEEEEE); 
    directionalLight.position.set(1, 1, 1).normalize(); 
    scene.add(directionalLight); 

      // Cube 
      for (var i = 0; i < 6; i ++) { 
       var img = new Image(); 
       img.src = 'test.png'; 
       var tex = new THREE.Texture(img); 
       img.tex = tex; 
       img.onload = function() { this.tex.needsUpdate = true; }; 
       var mat = new THREE.MeshLambertMaterial({map: tex}); 
       materials.push(mat); 
      } 

      cubeGeo = new THREE.CubeGeometry(200,200,200,1,1,1); 
      cubeGeo.uvsNeedUpdate = true; 
      cubeGeo.dynamic = true; 

      cube = new THREE.Mesh(cubeGeo, new THREE.MeshFaceMaterial(materials)); 

      cube.position.y = 150; 
      scene.add(cube); 

      renderer = new THREE.WebGLRenderer({antialias:true}); 
      renderer.setSize(window.innerWidth, window.innerHeight); 

      // enable shadows on the renderer 
      renderer.shadowMapEnabled = true; 
      container.appendChild(renderer.domElement); 

      stats = new Stats(); 
      stats.domElement.style.position = 'absolute'; 
      stats.domElement.style.top = '0px'; 
      container.appendChild(stats.domElement); 

      document.addEventListener('mousedown', onDocumentMouseDown, false); 
      document.addEventListener('touchstart', onDocumentTouchStart, false); 
      document.addEventListener('touchmove', onDocumentTouchMove, false); 

      window.addEventListener('resize', onWindowResize, 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 onDocumentMouseDown(event) { 
      event.preventDefault(); 

      document.addEventListener('mousemove', onDocumentMouseMove, false); 
      document.addEventListener('mouseup', onDocumentMouseUp, false); 
      document.addEventListener('mouseout', onDocumentMouseOut, false); 

      mouseXOnMouseDown = event.clientX - windowHalfX; 
      targetRotationOnMouseDown = targetRotation; 
     } 

     function onDocumentMouseMove(event) { 
      mouseX = event.clientX - windowHalfX; 
      targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.02; 
     } 

     function onDocumentMouseUp(event) { 
      document.removeEventListener('mousemove', onDocumentMouseMove, false); 
      document.removeEventListener('mouseup', onDocumentMouseUp, false); 
      document.removeEventListener('mouseout', onDocumentMouseOut, false); 
     } 

     function onDocumentMouseOut(event) { 
      document.removeEventListener('mousemove', onDocumentMouseMove, false); 
      document.removeEventListener('mouseup', onDocumentMouseUp, false); 
      document.removeEventListener('mouseout', onDocumentMouseOut, false); 
     } 

     function onDocumentTouchStart(event) { 
      if (event.touches.length === 1) { 
       event.preventDefault(); 
       mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX; 
       targetRotationOnMouseDown = targetRotation; 
      } 
     } 

     function onDocumentTouchMove(event) { 
      if (event.touches.length === 1) { 
       event.preventDefault(); 
       mouseX = event.touches[ 0 ].pageX - windowHalfX; 
       targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.05; 
      } 
     } 


     function animatex(dir) { 
      cubeGeo.faceVertexUvs[0][5] = [new THREE.UV(1, 0), new THREE.UV(1, 1), new THREE.UV(0, 1), new THREE.UV(0, 0)]; 
      cubeGeo.uvsNeedUpdate = true; 
      animate2(dir); 
     } 

     var anim = 0; 
     function animate2(dir) { 
       requestAnimationFrame(function() { 
        cubeGeo.faceVertexUvs[0][5] = [new THREE.UV(1, 0), new THREE.UV(1, 1), new THREE.UV(0, 1), new THREE.UV(0, 0)]; 
        cubeGeo.uvsNeedUpdate = true; 
        if(anim == 1) { 
         animate2(dir); 
        } 
       }); 
       render2(); 
       stats.update(); 
     } 

     function render2() { 
      cube.rotation.x = cube.rotation.x+0.06; 
      renderer.render(scene, camera); 
     } 

     function animate() { 
      requestAnimationFrame(animate); 
      render(); 
      stats.update(); 

     } 

     function render() { 
      cube.rotation.y += (targetRotation - cube.rotation.y) * 0.05; 
      $('#test').html(cube.rotation.y); 
      renderer.render(scene, camera); 
     } 

    </script> 
    <div id="up" style="position:absolute;z-index:500000;left:100px;top:20px;" class="nav">up</div> 
    <div id="down" style="position:absolute;z-index:500000;left:100px;top:40px;" class="nav">down</div> 
    <div id="left" style="position:absolute;z-index:500000;left:100px;top:60px;" class="nav">left</div> 
    <div id="right" style="position:absolute;z-index:500000;left:100px;top:80px;" class="nav">right</div> 
    <div id="test" style="position:absolute;z-index:500000;left:100px;top:100px;"> </div> 
    <script> 
     var _interval = 0; 
     $(document).ready(function(){ 
     $('.nav').mouseover(function() { 
      switch($(this).prop('id')) { 
       case 'up': 
        anim = 1; 
        animatex('up'); 
       break; 
      } 
     }); 

     $('.nav').mouseout(
      function() { 
       anim = 0; 
      } 
     ); 
     }); 
     </script> 
    </body> 
</html> 




mesh.geometry.uvsNeedUpdate = true; 

此鏈接可能會有幫助。 https://github.com/mrdoob/three.js/issues/667

+0

我沒有看到任何代碼。嘗試將其添加到您的原始問題,我會看看它。 –

+0

我明白了。非常感謝,它的作用像魅力! –