当前位置: 首页>后端>正文

three.js 学习之路

中文官网:https://threejs.org/docs/index.html#manual/zh/introduction/Creating-a-scene
学习视频地址:
b站-three.js 学习教程---适合初学者
3D教程 three.js---幽默有趣的demo合集(https://www.youtube.com/c/BrunoSimon/videos:搬运自youtube大佬Bruno Simon的three.js教程)

练习1:月球绕地球转

// 声明全局变量
            let camera, scene, renderer;
            let moon, earth;
            let clock = new THREE.Clock();
            // 实例化纹理加载器
            const textureLoader = new THREE.TextureLoader();

            // 地球和月球半径大小
            const EARTH_RADIUS = 2.5;
            const MOON_RADIUS = 0.27;
            // 实例化相机
            camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 2000);
            camera.position.set(10, 5, 20);

            // 实例化场景
            scene = new THREE.Scene();
            // 创建聚光灯光源
            const dirLight = new THREE.SpotLight(0xffffff);
            dirLight.position.set(0, 0, 10);
            dirLight.intensity = 2;
            dirLight.castShadow = true;
            scene.add(dirLight);
            // 添加环境光
            const aLight = new THREE.AmbientLight(0xffffff);
            aLight.intensity = 0.3;
            scene.add(aLight);

            const moonGeometry = new THREE.SphereGeometry(MOON_RADIUS, 16, 16);
            const moonMaterial = new THREE.MeshPhongMaterial({
                map: textureLoader.load(moonJpg)
            })
            moon = new THREE.Mesh(moonGeometry, moonMaterial);
            moon.receiveShadow = true;
            moon.castShadow = true;
            scene.add(moon);

            // earth
            const earthGeometry = new THREE.SphereGeometry(EARTH_RADIUS, 16, 16);
            const earthMaterial = new THREE.MeshPhongMaterial({
                shininess: 5,
                map: textureLoader.load(earthJpg),
                specularMap: textureLoader.load(earthSJpg),
                normalMap: textureLoader.load(earthNJpg)
            })
            earth = new THREE.Mesh(earthGeometry, earthMaterial);
            earth.receiveShadow = true;
            earth.castShadow = true;
            scene.add(earth);

            const earthDiv = document.createElement('div');
            earthDiv.className = 'label';
            earthDiv.textContent = 'Earth';

            const earthLabel = new CSS2DObject(earthDiv);
            earthLabel.position.set(0, EARTH_RADIUS - 0.5, 0);
            earth.add(earthLabel)

            const moonDiv = document.createElement('div');
            moonDiv.className = 'label';
            moonDiv.textContent = 'Moon';

            const moonLabel = new CSS2DObject(moonDiv);
            moonLabel.position.set(0, MOON_RADIUS, 0);
            moon.add(moonLabel)

            // 创建渲染器
            renderer = new THREE.WebGLRenderer({
                alpha: true
            });
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);

            // 渲染阴影
            renderer.shadowMap.enabled = true;
            document.body.appendChild(renderer.domElement);

            // 标签渲染器
            let labelRenderer = new CSS2DRenderer();
            labelRenderer.setSize(window.innerWidth, window.innerHeight);
            labelRenderer.domElement.style.position = 'absolute';
            labelRenderer.domElement.style.top = '0px';
            document.body.appendChild(labelRenderer.domElement);

            // 绑定控制和摄像头
            var oldTime = 0;
            function animate() {
                const elapsed = clock.getElapsedTime();
                moon.position.set(Math.sin(elapsed) * 5, 0, Math.cos(elapsed) * 5);

                // 地球自传
                var axis = new THREE.Vector3(0, 1, 0);
                earth.rotateOnAxis(axis, (elapsed - oldTime) * Math.PI / 10);
                renderer.render(scene, camera)
                labelRenderer.render(scene, camera)
                oldTime = elapsed;
                requestAnimationFrame(animate)
            }
            animate();
            window.onresize = function() {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(window.innerWidth, window.innerHeight);
            }

以上代码是学习视频时记录下来的,并非原创。若想放到vue项目中,将渲染器放到已有div容器中,可将renderer.domElement 添加到已有dom元素中,方便控制宽高.这里,可参见我整理的代码:https://github.com/scrollHeart/threejsDemo


https://www.xamrdz.com/backend/3mz1940919.html

相关文章: