# threejs入门体验

# 文档

# 概念

属性名称 描述
场景 是物体、光源等元素的容器
相机 场景中的相机,代替人眼去观察,场景中只能添加一个,一般常用的是透视相机(PerspectiveCamera),可以很好的模仿人眼
物体对象 包括二维物体(点、线、面)、三维物体、模型等
光源 场景中的光照,如果不添加光照场景将会是一片漆黑,包括全局光、平行光、点光源等
渲染器 场景的渲染方式,如 WebGL、canvas2D、css3D
控制器 可通过键盘、鼠标控制相机的移动

# 目标

  • 开始使用 Three.js 库
  • 创建第一个场景
  • 在场景中放置一些东西
  • 让它动起来
  • 给场景一些光

# 步骤

  • 每当使用 Three.js 时,需要设置的基础是场景、相机和渲染器。

  • 从一个场景开始,稍后将添加它,但现在将创建一个不带参数的新场景元素,相机将使用 PerspectiveCamera 选项,需要给这个函数四个参数:

    1. 视野:相机视角的宽度。
    2. 纵横比:像电视屏幕一样,如宽度/高度。
    3. 剪裁平面附近:比这更近的元素不会在屏幕上呈现。基本上使用 0。
    4. 远剪裁平面:比这更远的元素不会渲染,值太高可能会导致性能问题。
  • 渲染器采用选项对象{antialiasing: true}以便在要创建的立方体上具有更平滑的边缘,并且将渲染器的大小设置为整个窗口的大小,并告诉它将自己附加到 HTML 页面的正文中

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
);
const renderer = new THREE.WebGLRenderer({ antialias: true });

renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor('#222222');
document.body.appendChild(renderer.domElement);
  • 创建立方体,需要三个核心元素来处理想要渲染的每个对象:
    1. 几何:物体的形状,由顶点和物体的平面组成。
    2. 材质:像颜色这样的东西
    3. 网格:几何体和材质的组合
const geometry = new THREE.BoxGeometry(1, 1, 1); 
const material = new THREE.MeshStandardMaterial({
  color: 0xff0051,
  flatShading: true,
  metalness: 0,
  roughness: 1,
});
  • 我们需要一个环境光,定义它颜色,以及亮度。环境光无所不在,同样适用于所有事物。它不能投射阴影,因为它没有方向
const ambientLight = new THREE.AmbientLight(0xffffff, 0.2);
scene.add(ambientLight);
  • 接下来还要创建一个点光源,可以把它想象成灯泡,来自此的光将从原点均匀地向各个方向传播。
const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.position.set(25, 50, 25);
scene.add(pointLight);
  • 至此就可以看到一个完整的效果了,完整代码如下:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            background-color: green;
        }

        canvas {
            width: 100%;
            height: 100%;
        }
    </style>
</head>

<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.js"></script>
    <script>
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({ antialias: true });

        renderer.setSize(window.innerWidth, window.innerHeight);

        renderer.setClearColor('#222222');
        document.body.appendChild(renderer.domElement);
        camera.position.z = 5;

        // 立体方
        const geometry = new THREE.BoxGeometry(1, 1, 1); //BoxGeometry 方法将接受构造函数参数,分别是盒子的宽度、高度和深度。
        const material = new THREE.MeshStandardMaterial({
            color: 0xff0051,
            flatShading: true,
            metalness: 0,
            roughness: 1,
        });
        const cube = new THREE.Mesh(geometry, material); //网格模型对象Mesh
        scene.add(cube); //通过.add()方法,把网格模型mesh添加到三维场景scene中

        // 维数据集
        const geometry2 = new THREE.BoxGeometry(3, 3, 3);
        const material2 = new THREE.MeshBasicMaterial({
            color: '#ffffff',
            wireframe: true,
            transparent: true,
        });
        const wireframeCube = new THREE.Mesh(geometry2, material2);
        scene.add(wireframeCube);

        // 环境光
        const ambientLight = new THREE.AmbientLight(0xffffff, 0.2);
        scene.add(ambientLight);

        // 点光源
        const pointLight = new THREE.PointLight(0xffffff, 1);
        pointLight.position.set(25, 50, 25);
        scene.add(pointLight);

        function animate() {
            requestAnimationFrame(animate);
            cube.rotation.x += 0.04; //x轴旋转
            cube.rotation.y += 0.04; //y轴旋转
            wireframeCube.rotation.x -= 0.01;
            wireframeCube.rotation.y -= 0.01;
            renderer.render(scene, camera);
        }
        animate();

        // resize 事件
        window.addEventListener('resize', () => {
            let width = window.innerWidth;
            let height = window.innerHeight;
            renderer.setSize(width, height);
            camera.aspect = width / height;
            camera.updateProjectionMatrix();
        });

    </script>
</body>

</html>
Last Updated: 11/9/2023, 6:56:07 AM