Three.js 三维模型(一)

简介

今天主要给搭建介绍下three.js的基本使用,本篇是基于笔者在16年给做的一个项目的demo版进行讲解的,笔者当时采用Html5和JS进行编写的。可能大家会问有没有vue、React 、angular版的。这些笔者后面有时间的时候一定会给大家介绍。

其实编程的本源在于提炼属于自己的哲学思想,不授予任何技术和编程语言的限制。就像给你时间你可以用英语或者世界上任何一种语言写出一篇精美的文章。但是文章的精美并不是他用什么语言编写的,而是他的中心思想。我们要把复杂的问题简单化,删繁就简。

代码片段

  • 首先,当用户访问网页时,该网页将加载Three.js库以及其他相关脚本文件,包括DDSLoader.js、MTLLoader.js、OBJLoader.js、tween.min.jsOrbitControls.js。这些文件为Three.js的功能提供了必要的支持。
  • 在页面的<body> 标签中,我们创建一个<div>元素,其id属性设置为"container",作为Three.js渲染结果的容器。
  • 在JavaScript部分,我们定义了变量camera、scene和renderer,用于存储相机、场景和渲染器的实例。mouseX和mouseY变量用于存储鼠标的位置。
  • 接下来,我们定义了init()函数,用于初始化Three.js场景。函数首先获取容器元素,并创建一个透视相机。相机被放置在(0, 0,
    450)的位置,其fov属性设置为460度,远近平面分别为1和20000。然后,我们创建一个场景,并设置其背景颜色为灰色(0xcccccc)。环境光源和点光源被添加到场景中。
  • 在加载模型的过程中,我们定义了一个回调函数onProgress,用于跟踪模型加载的进度。首先,使用MTLLoader加载模型的材质文件(MTL文件),并在加载完成后预加载材质。然后,使用OBJLoader加载模型的几何体文件(OBJ文件),并将之前加载的材质应用到模型上。加载完成后,将模型添加到场景中。
  • 然后,我们创建一个WebGL渲染器,并设置其输出编码和像素比。将渲染器的DOM元素添加到之前创建的容器中。
  • 为了实现相机的交互控制,我们使用OrbitControls来创建一个控制器,并绑定到相机和渲染器的DOM元素上。控制器允许用户通过鼠标拖拽和滚动来控制相机的位置和视角。
  • 最后,我们定义了onWindowResize()函数,用于在窗口大小变化时调整相机和渲染器的尺寸。该函数更新相机的宽高比并更新渲染器的大小。
  • 最后,我们定义了animate()函数,使用requestAnimationFrame()递归地调用该函数来更新和渲染场景。在每一帧中,渲染器将呈现场景和相机的内容。
  • 在页面加载完成后,我们调用init()函数进行初始化,并开始动画循环调用animate()函数。
  • 这样,当用户访问该网页时,将显示一个包含3D模型的Three.js场景,并允许用户通过鼠标交互来控制相机的位置和视角。
  • 请注意,为了使代码正常运行,你需要确保在相应的目录中有正确的资源文件(如模型文件、材质文件等)和脚本文件。
<!DOCTYPE html>
<html lang="en">

<head>
    <title>侍女佣</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <link type="text/css" rel="stylesheet" href="./css/main.css">
</head>

<body>

  

    <script src="./js/three.js"></script>
    <script src="./js/DDSLoader.js"></script>
    <script src="./js/MTLLoader.js"></script>
    <script src="./js/OBJLoader.js"></script>
    <script src="./js/tween.min.js"></script>
    <script src="./js/OrbitControls.js"></script>

    <script>
        // 创建变量来存储相机、场景和渲染器
        var camera, scene, renderer;

        // 存储鼠标位置的变量
        var mouseX = 0, mouseY = 0;

        // 窗口的一半宽度和高度
        var windowHalfX = window.innerWidth / 2;
        var windowHalfY = window.innerHeight / 2;

        // 初始化函数
        function init() {
      
      
            // 创建一个容器元素,并将其添加到页面中
            const container = document.createElement('div');
            document.body.appendChild(container);

            // 创建透视相机,并设置位置
            camera = new THREE.PerspectiveCamera(460, window.innerWidth / window.innerHeight, 1, 20000);
            camera.position.z = 450;

            // 创建场景,并设置背景颜色
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0xcccccc);

            // 创建环境光源并添加到场景中
            const ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
            scene.add(ambientLight);

            // 创建点光源并将其添加到相机中,再将相机添加到场景中
            const pointLight = new THREE.PointLight(0xffffff, 1);
            camera.add(pointLight);
            scene.add(camera);

            // 加载模型的回调函数
            const onProgress = function (xhr) {
      
      
                if (xhr.lengthComputable) {
      
      
                    const percentComplete = xhr.loaded / xhr.total * 100;
                    console.log(Math.round(percentComplete, 2) + '% downloaded');
                }
            };

            // 使用MTLLoader加载材质文件
            new THREE.MTLLoader()
                .setPath('./model/sny/')
                .load('sny.mtl', function (materials) {
      
      
                    materials.preload();

                    // 使用OBJLoader加载OBJ文件并应用之前加载的材质
                    new THREE.OBJLoader()
                        .setMaterials(materials)
                        .setPath('./model/sny/')
                        .load('sny.obj', function (object) {
      
      
                            object.position.y = -5;
                            scene.add(object);
                        }, onProgress);
                });

            // 创建WebGL渲染器,并设置相关参数
            renderer = new THREE.WebGLRenderer();
            renderer.outputEncoding = THREE.sRGBEncoding;
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);

            // 将渲染器的DOM元素添加到容器中
            container.appendChild(renderer.domElement);

            // 创建OrbitControls来控制相机
            const controls = new THREE.OrbitControls(camera, renderer.domElement);
            controls.minDistance = 100;
            controls.maxDistance = 2000;

            // 监听窗口大小变化事件,触发onWindowResize函数
            window.addEventListener('resize', onWindowResize);
        }

        // 当窗口大小变化时调整相机和渲染器的尺寸
        function onWindowResize() {
      
      
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        // 递归地调用animate函数,更新和渲染场景
        function animate() {
      
      
            requestAnimationFrame(animate);
            renderer.render(scene, camera);
        }

        // 初始化并开始动画循环
        init();
        animate();
    </script>

</body>

</html>

效果图展示

以下是基于vscode的live server运行的结果,细节可以根据api自己调整。
在这里插入图片描述

注意:在开发three.js的过程中一定要注意兼容性的问题,目前最新版本兼容性会有问题,建议采用稳定版本

到此笔者的讲解完毕,需要js文件包的请到本页下载或者联系笔者。谢谢大家的支持

猜你喜欢

转载自blog.csdn.net/weixin_43114209/article/details/131633988