Three.js学习之旅--初识

354 阅读4分钟

最近对Three.js比较感兴趣,打算系统的学习一下Three.js,接下来会打卡记录--Three.js学习之旅,本篇文章为打卡记录的第一篇!

安装

npm init

npm install three

引入

新建html文件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three.js学习之旅-初时</title>
</head>

<body>
    <script type="importmap">
       {
        "imports":{
            "three":"./node_modules/three/build/three.module.js"
        }
       }
    </script>


    <script type="module">
        import * as THREE from 'three';
        console.log(Three)
    </script>
</body>

</html>

其中type="importmap"类似与webpackresolve.alias别名;type="module"是使用ES Module模块化;

配置文档

参数详情,请查阅以下配置文档:

three.js原文档

three.js中文网

创建场景、物体

// 创建场景
const scene = new THREE.Scene();
// 创建长方形几何体
const geometry = new THREE.BoxGeometray();
// 创建物体材质
const meterial = new THREE.MeshBasicMeterial({
    color: 0x0000FF
});
// 创建物体-网格模型
const mesh = new THREE.Mesh(geometry, meterial);
// 设置物体的位置
mesh.position.set(0, 0, 0);
// 将物体添加到场景中
scene.add(mesh);

定义画布大小

// 定义canvas画布
const width = window.innerWidth;
const height = window.innerHeight;

创建相机

// 创建相机(透视投影相机)
//PerspectiveCamera(fov, aspect, near, far)
const camera = new THREE.PerspectiveCamera(30, width / height, 0.1, 1000); // 定义相机视距大小
// 设置相机位置
camera.position.set(200, 200, 200);
// 设置相机观察目标点
camera.lookAt(0, 0, 0);
// 或者直接看物体
camera.lookAt(mesh.position);

创建渲染器

// 创建渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染画布大小
renderer.setSize(width,height);
// 渲染场景、相机
renderer.render(scene,camera);
// 将渲染画布插入到body中
document.body.appendChild(renderer.domElement); //renderer.domElement为渲染画布元素

效果:

three01-1.jpg

添加辅助观察坐标系

// 添加辅助观察坐标系
// 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴 -- R G B
// AxesHelper( size : Number ) size -- (可选的) 表示代表轴的线段长度. 默认为 1.
const axesHelper = new THREE.AxesHelper(50);
scene.add(axesHelper);

添加轨道控制器

// 路径别名
<script type="importmap">
{
    "imports":{
        "three":"./node_modules/three/build/three.module.js",
        "three/addons/":"./node_modules/three/examples/jsm/"
    }
}
</script>

// 引入轨道控制器
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
// 添加轨道控制器
const controls  = new OrbitControls(camera,renderer.domElement);
// 监听控制器事件
controls.addEventListener('change',()=>{
    // 执行渲染操作
    renderer.render(scene,camera)
})

three01-2.gif

添加光源

// 改变物体材质
// 创建物体材质-基础网格材质(不受光照影响)
// const meterial = new THREE.MeshBasicMaterial({
//     color: 0x0000FF
// });
//漫反射材质(受光照影响)
const meterial = new THREE.MeshLambertMaterial({
    color: 0x0000FF
});
//创建光源
//环境光:没有特定方向,整体改变场景的光照明暗
const light = new THREE.AmbientLight( 0xffffff ); 
scene.add( light );
// 添加平行光
const directionalLight = new THREE.DirectionalLight(0xffffff, 2);
// 设置光源位置
directionalLight.position.set(80, 40, 60);
// 方向光指向对象网格模型mesh,可以不设置,默认的位置是0,0,0
directionalLight.target = mesh;
scene.add(directionalLight);

three01-3.gif

可以看出物体已产生由平行光照射产生的棱角

物体运动

// 旋转物体
function render(){
    // 每次执行时render()函数时,重新渲染
    renderer.render(scene,camera);
    // 物体沿x轴旋转
    mesh.rotateX(0.1);
    requestAnimationFrame(render) //下一帧执行函数render
}
render()

three01-4.gif

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three.js学习之旅-初识</title>
    <script type="importmap">
        {
         "imports":{
             "three":"./node_modules/three/build/three.module.js",
             "three/addons/":"./node_modules/three/examples/jsm/"
         }
        }
     </script>
</head>

<body>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
    <script type="module">
        import * as THREE from 'three';
        // 引入轨道控制器
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

        // 创建场景
        const scene = new THREE.Scene();
        // 创建长方形几何体
        const geometry = new THREE.BoxGeometry(30, 30, 30); //长 宽 高
        // 创建物体材质-基础网格材质(不受光照影响)
        // const meterial = new THREE.MeshBasicMaterial({
        //     color: 0x0000FF
        // });
        //漫反射材质(受光照影响)
        const meterial = new THREE.MeshLambertMaterial({
            color: 0x0000FF
        });
        // 创建物体-网格模型
        const mesh = new THREE.Mesh(geometry, meterial);
        // 设置物体的位置
        mesh.position.set(0, 0, 0);
        // 将物体添加到场景中
        scene.add(mesh);


        // 定义canvas画布
        const width = window.innerWidth;
        const height = window.innerHeight;


        // 创建相机(透视投影相机)
        //PerspectiveCamera(fov, aspect, near, far)
        const camera = new THREE.PerspectiveCamera(30, width / height, 0.1, 1000); // 定义相机视距大小
        // 设置相机位置
        camera.position.set(200, 200, 200);
        // 设置相机观察目标点
        camera.lookAt(0, 0, 0);
        // 或者直接看物体
        camera.lookAt(mesh.position);


        // 添加辅助观察坐标系
        // 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴 -- R G B
        // AxesHelper( size : Number ) size -- (可选的) 表示代表轴的线段长度. 默认为 1.
        const axesHelper = new THREE.AxesHelper(50);
        scene.add(axesHelper);

        //创建光源
        // 环境光
        const light = new THREE.AmbientLight( 0xffffff ); 
        scene.add( light );

        // 平行光
        const directionalLight = new THREE.DirectionalLight(0xffffff, 2);
        // 设置光源位置
        directionalLight.position.set(80, 40, 60);
        // 方向光指向对象网格模型mesh,可以不设置,默认的位置是0,0,0
        directionalLight.target = mesh;
        scene.add(directionalLight);
   
        // 创建渲染器
        const renderer = new THREE.WebGLRenderer();
        // 设置渲染画布大小
        renderer.setSize(width, height);
        // 渲染场景、相机
        renderer.render(scene, camera);
        // 将渲染画布插入到body中
        document.body.appendChild(renderer.domElement); //renderer.domElement为渲染画布元素
 
        
        // 添加轨道控制器
        const controls  = new OrbitControls(camera,renderer.domElement);
        // 监听控制器事件
        controls.addEventListener('change',()=>{
            // 执行渲染操作
            renderer.render(scene,camera)
        })


        // 旋转物体
        function render(){
            // 每次执行时render()函数时,重新渲染
            renderer.render(scene,camera);
            // 物体沿x轴旋转
            mesh.rotateX(0.1);
            requestAnimationFrame(render) //下一帧执行函数render
        }
        render()
    </script>
</body>

</html>