立方体的背面纹理垂直翻转



我目前正在尝试制作一个带有纹理的旋转立方体。我还希望立方体通过使用控件(鼠标悬停时旋转立方体的箭头图像)在x轴和y轴上旋转(来回)。在x轴上旋转时,立方体的背面是倒置的。

我知道这与UV贴图的工作方式有关。所以我试着在多维数据集初始化时纠正这一点,效果很好。但当我试图在y轴上旋转立方体时,纹理又颠倒了。因此,我学会了必须根据旋转请求随时更改纹理方向。

但这对我不起作用。在初始化多维数据集后,我找不到更改"faceVertexUvs[0][5]"的方法。尝试在初始化时为多维数据集几何体设置"needsUpdate"没有帮助。

希望我说清楚了。这个问题有什么解决办法吗?

提前感谢Michael

为了更好地说明我的问题:我在这里发布了我的源代码。

它无法在JsFiddle中演示,因为不允许使用来自另一个域的纹理图像(CORS也不起作用)。只需复制粘贴以下代码,并在本地将其保存为"test.html"即可。此处提供纹理图像:http://www.mikelmade.de/cors/t.png.它应该和"test.html"在同一个目录中。在支持WebGL的浏览器中打开"testhtml",然后将鼠标向上移动,你应该明白我的意思了。

<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>

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

最新更新