0

我目前正在尝试制作带有纹理的旋转立方体。我还希望立方体通过使用控件(在鼠标悬停时旋转立方体的箭头图像)在它的 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>
4

1 回答 1

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

于 2013-02-07T14:34:14.133 回答