three.js - 立方体的背面纹理垂直翻转

时间:2013-02-07 09:23:47

标签: three.js

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

我知道这与UV映射的工作方式有关。所以我试图纠正多维数据集初始化,这很好。但是,当我尝试在其y轴上旋转立方体时,纹理再次颠倒。所以我了解到我必须动态改变纹理方向 - 根据旋转请求。

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

希望我明白自己。这个问题有某种解决方案吗?

提前致谢 迈克尔

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

无法在JsFiddle中演示,因为不允许使用来自其他域的纹理图像(并且CORS不起作用)。只需复制粘贴以下代码并将其另存为“test.html”本地。这里可以使用纹理图像:http://www.mikelmade.de/cors/t.png。它应与“test.html”位于同一目录中。在支持WebGL的浏览器中打开“test.html”,然后将鼠标移到“up”上,您应该看到我的意思。

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

1 个答案:

答案 0 :(得分: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