OrbiterControls 在 three.js 应用程序中无法正常工作

OrbiterControls not working properly in three.js app

我正在尝试创建一个基本场景,其中包含一个可以围绕中心旋转的轨道器控件,即始终注视 (0,0,0)。我希望它的行为完全像这样 https://threejs.org/examples/misc_controls_orbit.html。但在我的版本中,如果我单击并拖动到 left/right,相机只会旋转一圈,始终注视着 (0,0,0)。我该如何解决这个问题?

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>My first three.js app</title>
        <style>
            body { 
                margin: 0; 
            }
        </style>
    </head>
    <body>
        <script type="module">
            import * as THREE from 'https://threejs.org/build/three.module.js';
            import { OrbitControls } from 'https://threejs.org/examples/jsm/controls/OrbitControls.js';

            const scene = new THREE.Scene();
            const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

            const renderer = new THREE.WebGLRenderer();
            renderer.setSize( window.innerWidth, window.innerHeight );
            document.body.appendChild( renderer.domElement );

            // ADD LIGHT
            const light = new THREE.PointLight(0xffffff, 2)
            light.position.set(0, 5, 10)
            scene.add(light)

            // ADD ORBITER
            const controls = new OrbitControls( camera, renderer.domElement );
            controls.listenToKeyEvents( window );
            controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
            controls.dampingFactor = 0.05;
            //controls.screenSpacePanning = false;
            //controls.minDistance = 100;
            //controls.maxDistance = 500;
            //controls.maxPolarAngle = Math.PI / 2;
            //controls.minPolarAngle = Math.PI / 2;
            //controls.maxPolarAngle = Math.PI / 2;

            camera.position.set(0, -5, 5);
            camera.lookAt( 0, 0, 0 );
            camera.up.set( 0, 0, 1 );
            //controls.target = new THREE.Vector3(0, 0, 0);
            controls.update();


            // ADD CUBE
            const geometry = new THREE.BoxGeometry();
            const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
            const cube = new THREE.Mesh( geometry, material );
            scene.add( cube );


            // ADD MAP
            const loader = new THREE.TextureLoader();
            const height = loader.load('/data/images/height.png');
            const texture = loader.load('/data/images/height.png');

            const map_geometry = new THREE.PlaneBufferGeometry(10,10,64,64);
            const map_material = new THREE.MeshStandardMaterial({
                color:'orange',
                //side: THREE.DoubleSide,
                map:texture,
                displacementMap: height,
                displacementScale: 0.5,
                //alphaMap: alpha,
                //transparent:true
            });

            const map_plane = new THREE.Mesh(map_geometry, map_material);
            //map_plane.position.set(0, 0, 0);
            scene.add( map_plane );

            // RENDER
            function animate() {
                requestAnimationFrame( animate );
                //cube.rotation.x += 0.01;
                //cube.rotation.y += 0.01;
                renderer.render( scene, camera );
            }
            animate();
        </script>
    </body>
</html>

代码需要多次修改。请改用下面的代码并将其与您的代码进行比较,以找出我更改了​​哪些部分。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>My first three.js app</title>
        <style>
            body {
                padding: 0;
                margin: 0;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <script type="module">
            import * as THREE from 'https://threejs.org/build/three.module.js';
            import {OrbitControls} from 'https://threejs.org/examples/jsm/controls/OrbitControls.js';

            // BUILDING THE SCENE
            const scene = new THREE.Scene();

            // ADDING CAMERA
            const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.set(0, -5, 5);
            scene.add(camera);

            // CREATING THE RENDERER
            const renderer = new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);

            // ADD LIGHT
            const light = new THREE.PointLight(0xffffff, 2);
            light.position.set(0, 5, 10);
            scene.add(light);

            // ADD ORBITER
            const controls = new OrbitControls(camera, renderer.domElement);
            controls.maxPolarAngle = Math.PI/2.2;
            controls.minDistance = 5;
            controls.maxDistance = 10;
            controls.target.set(0, 0, 0);

            // ADD CUBE
            const geometry = new THREE.BoxGeometry();
            const material = new THREE.MeshBasicMaterial({color: 0x00ff00});
            const cube = new THREE.Mesh(geometry, material);
            cube.position.set(0, .5, 0);
            scene.add(cube);

            // ADD MAP
            const loader = new THREE.TextureLoader();
            const height = loader.load('/data/images/height.png');
            const texture = loader.load('/data/images/height.png');

            const map_geometry = new THREE.PlaneBufferGeometry(10,10,64,64);
            const map_material = new THREE.MeshStandardMaterial({
                color:'orange',
                side: THREE.DoubleSide,
                map:texture,
                displacementMap: height,
                displacementScale: 0.5,
            });

            const map_plane = new THREE.Mesh(map_geometry, map_material);
            map_plane.rotation.x = Math.PI/2;
            scene.add(map_plane);

            window.addEventListener('resize', onWindowResize, false);

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

            // ANIMATING THE SCENE
            function animate() {
                controls.update();
                requestAnimationFrame(animate);
                renderer.render(scene, camera);
            }
            animate();
        </script>
    </body>
</html>
  1. 在animate函数中写入controls.update();
  2. controls.maxPolarAngle = Math.PI/2.2;不让相机下地
  3. controls.target.set(0, 0, 0); 使控制楼梯在中心。
  4. 我添加了map_plane.rotation.x = Math.PI/2;所以飞机会像地板一样水平放置。
  5. 并且 side: THREE.DoubleSide, 帮助地板从所有角度都可见。
  6. 我还在脚本中添加了一个 onWindowResize 函数来使应用程序响应。现在,它会在调整大小时响应浏览器的宽度和高度。
  7. 在 CSS 的情况下,页面也有默认填充。因此,在 CSS 代码中添加 padding: 0; 也是一个不错的主意。