其他分享
首页 > 其他分享> > three.js入门一:入门demo讲解

three.js入门一:入门demo讲解

作者:互联网

环境:

关于threejs:
开源web3d引擎

github:https://github.com/mrdoob/three.js/
官网:https://threejs.org/
中文教程:http://www.yanhuangxueyuan.com/WebGL/

1. 入门Demo

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="js/three.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>

    <script>
        //基础准备
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        // 设置为51,发现z轴的箭头被切掉一部分
        // const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 51, 1000);
        // var aspectratio = window.innerWidth / window.innerHeight;//1920/969=1.98
        //const camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000);
        camera.position.set(0, 0, 100);

        // 相机的up值在这里设置生效
        // camera.up.x = 0;
        // camera.up.y = 1;
        // camera.up.z = 0;

        camera.lookAt(0, 0, 0);
        console.log(camera);
        const renderer = new THREE.WebGLRenderer({
            antialias: true
        });
        renderer.setSize(window.innerWidth, window.innerHeight);
        // renderer.setSize(500, 500);
        document.body.appendChild(renderer.domElement);


        // 轴线
        //x轴线 红色
        var material = new THREE.LineBasicMaterial({ color: 0xff0000 });
        var points = [];
        points.push(new THREE.Vector3(0, 0, 0));
        points.push(new THREE.Vector3(50, 0, 0));
        var geometry = new THREE.BufferGeometry().setFromPoints(points);
        var line = new THREE.Line(geometry, material);
        scene.add(line);
        //箭头1
        points = [];
        points.push(new THREE.Vector3(50, 0, 0));
        points.push(new THREE.Vector3(48, 2, 0));
        geometry = new THREE.BufferGeometry().setFromPoints(points);
        line = new THREE.Line(geometry, material);
        scene.add(line);
        //箭头2
        points = [];
        points.push(new THREE.Vector3(50, 0, 0));
        points.push(new THREE.Vector3(48, -2, 0));
        geometry = new THREE.BufferGeometry().setFromPoints(points);
        line = new THREE.Line(geometry, material);
        scene.add(line);

        //y轴线 绿色
        material = new THREE.LineBasicMaterial({ color: 0x00ff00 });
        points = [];
        points.push(new THREE.Vector3(0, 0, 0));
        points.push(new THREE.Vector3(0, 50, 0));
        geometry = new THREE.BufferGeometry().setFromPoints(points);
        line = new THREE.Line(geometry, material);
        scene.add(line);
        //箭头1
        points = [];
        points.push(new THREE.Vector3(0, 50, 0));
        points.push(new THREE.Vector3(2, 48, 0));
        geometry = new THREE.BufferGeometry().setFromPoints(points);
        line = new THREE.Line(geometry, material);
        scene.add(line);
        //箭头2
        points = [];
        points.push(new THREE.Vector3(0, 50, 0));
        points.push(new THREE.Vector3(-2, 48, 0));
        geometry = new THREE.BufferGeometry().setFromPoints(points);
        line = new THREE.Line(geometry, material);
        scene.add(line);

        //z轴线 蓝色
        material = new THREE.LineBasicMaterial({ color: 0x0000ff });
        // material = new THREE.LineBasicMaterial({ color: 0x000000 });
        points = [];
        points.push(new THREE.Vector3(0, 0, 0));
        points.push(new THREE.Vector3(0, 0, 50));
        geometry = new THREE.BufferGeometry().setFromPoints(points);
        line = new THREE.Line(geometry, material);
        scene.add(line);
        //箭头1
        points = [];
        points.push(new THREE.Vector3(0, 0, 50));
        points.push(new THREE.Vector3(2, 0, 48));
        geometry = new THREE.BufferGeometry().setFromPoints(points);
        line = new THREE.Line(geometry, material);
        scene.add(line);
        //箭头2
        points = [];
        points.push(new THREE.Vector3(0, 0, 50));
        points.push(new THREE.Vector3(-2, 0, 48));
        geometry = new THREE.BufferGeometry().setFromPoints(points);
        line = new THREE.Line(geometry, material);
        scene.add(line);


        //立方体
        geometry = new THREE.BoxGeometry(40, 40, 40);
        material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
        cube = new THREE.Mesh(geometry, material);
        cube.position.set(0, 0, 0);
        scene.add(cube);

        var lookX = 0, lookY = 0, lookZ = 0;
        const animate = function () {
            requestAnimationFrame(animate);

            // 相机的位置
            camera.position.x += 0.1;
            camera.position.y += 0.1;
            camera.position.z += 0.1;

            // 立方体的旋转
            // cube.rotation.x += 0.01;
            // cube.rotation.y += 0.01;
            // cube.rotation.z += 0.01;

            // 立方体的位置
            // cube.position.set(cube.position.x + 0.01, cube.position.y, cube.position.z);
            // cube.position.set(cube.position.x, cube.position.y + 0.01, cube.position.z);
            // cube.position.set(cube.position.x, cube.position.y, cube.position.z + 0.01);

            // 相机的摆放姿势(在这里设置无效)
            // camera.up.x=1;
            // camera.up.y=0;
            // camera.up.z=0;

            // 相机的lookAt
            // camera.lookAt(lookX += 0.01, lookY += 0.01, lookZ += 0.01)
            // camera.lookAt(lookX += 1, lookY, lookZ)
            renderer.render(scene, camera);
        };

        animate();
    </script>
</body>

</html>

效果图如下:
在这里插入图片描述

2. 坐标系

threejs使用的是右手坐标系,即:
在这里插入图片描述
默认情况下,threejs中的坐标轴如上所示:x轴在屏幕上从左到右,y轴在屏幕上从下到上,z轴穿透屏幕从内到外;我们也可以修改相机的参数(相机方向)使这个坐标系发生旋转,但无论怎么旋转都是右手坐标系。

可以将坐标系打印出来如下:
在这里插入图片描述

坐标系旋转操作:

旋转时需要确定轴方向以及轴上一点。
对于上图中立方体的旋转,我们控制它绕x轴旋转,则代码如下:

// 立方体的旋转
cube.rotation.x += 0.01;

这样旋转时,立方体就以经过它中心点(即立方体的position,这里将它设为(0,0,0))的x轴旋转,此时,立方体的旋转方向也符合右手螺旋定则(可以这么理解),即:大拇指指向x轴正方向,其他4指弯曲的方向是旋转的正方向。

3. 相机参数

1. 相机位置:
这个即观察者的位置,最易理解,示例代码:

camera.position.set(0, 0, 100);

2. 观察目标位置:
即眼睛看向哪里。可以看向坐标原点,也可以看向其他点,看的方向不同,自然得到的效果不同,示例代码:

camera.lookAt(0, 0, 0);

3. 相机方向:
即我们是站着看,还是躺着看,还是侧着身看,不同的姿势观察的效果不同,比如,我们侧着身子看到的东西是歪着的,倒过来看到的东西也是倒着的,示例代码:

 // 一般不需要修改此参数,注意此代码的位置,我在animate函数中设置不起作用,放在外面就可以
 camera.up.x = 0;
 camera.up.y = 1;
 camera.up.z = 0;

4. 相机的视场角(FOV)
即:眼睛看到的角度范围,如下图:
在这里插入图片描述
我们可以设置不同的值,观察效果,它的取值范围应该是(0,180),threejs给的demo是75度,一般取这个值没问题:
在这里插入图片描述
示例代码如下:

//视场角设置为75度
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

5. 相机的 aspect ratio
这个参数和图像的宽高比有关,一般我们将它设置为 window.innerWidth / window.innerHeight
它可以和渲染器的窗口大小配合使用,当它们宽高比一致时正常显示,否则渲染会发生变形,如下示例代码:

//将相机的aspect ratio宽高比设置为使用浏览器窗口(我的浏览器是:1920/769=1.98)
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
//...
const renderer = new THREE.WebGLRenderer({antialias: true});
//渲染的窗口宽高比和相机的aspect ratio值相同,正常显示不变形
renderer.setSize(window.innerWidth, window.innerHeight);
//渲染窗口设置为500*500,导致渲染的宽高比和相机的aspect ratio值不同,发生形变,此时可以将相机的aspect ratio调整为"1"
//renderer.setSize(500, 500);

6. 相机的near 和 far
这个参数表示,在距离相机[near,far]范围内的图形可显示,超出的内容要被剪切掉,可以理解为前后各切一刀。
注意:可以用这个参数提高渲染性能。

//设置为 距离相机[0.1,1000]范围内的图形可显示
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// 下面将 near设置为51,因为设置的箭头有两个线段的坐标为:(0, 0, 50)->(2, 0, 48)  (0, 0, 50)->(-2, 0, 48),而相机的位置在(0,0,100) 所以near设置为51后可以看到被切断的箭头
// const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 51, 1000);

在这里插入图片描述

最后示例代码:

https://download.csdn.net/download/u010476739/76901892

标签:入门,geometry,demo,THREE,three,window,points,new,camera
来源: https://blog.csdn.net/u010476739/article/details/122597958