three.js 安装方法、基础简介、创建基础场景

threejs简介

Three.js是一个基于JavaScript编写的开源3D图形库,‌利用WebGL技术在网页上渲染3D图形。‌ 它提供了许多高级功能,‌如几何体、‌纹理、‌光照、‌阴影等,‌使得开发者能够快速创建复杂且逼真的3D场景。‌
threejs提供了丰富的功能和工具,让开发者能够轻松的创建3D对象、设置灯光、添加动画、处理用户交互等。它支持多种3D格式的导入,如OBJ、GLTF等,也支持自定义的材质和着色器。
threejs相关文档:

threejs安装

在项目中引入threejs,比如你采用的是Vue + threejs或React + threejs技术栈,这很简单,threejs就是一个js库,直接通过npm命令安装即可。

npm install three

注意:很多基于threejs的库开发的三方库(比如ThreeBSP)对于threejs的版本有要求。可以指定版本安装(注意使用哪个版本,查看文档就对应的版本)。

// 比如安装124版本
npm install three@0.124.0

npm安装后,如何引入three.js

执行import * as THREE from 'three';,ES6语法引入three.js核心。

// 引入three.js
import * as THREE from 'three';

npm安装后,如何引入threejs其他扩展库

除了three.js核心库以外,在threejs文件包中example/js目录下,你还可以看到各种不同功能的扩展库。
一般来说,你项目用到那个扩展库,就引入哪个,用不到就不需要引入。

// 引入扩展库OrbitControls.js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// 引入扩展库GLTFLoader.js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

three.js基础

入门three.js的第一步就是认识场景Scene、相机Camera、渲染器**Renderer**三个基本概念。
在这里插入图片描述

场景Scene

场景能够让你在什么地方、摆放什么东西来交给three.js来渲染,这是你放置物体、灯光和摄像机的地方。场景本身不包含几何形状或材质,但是它可以包含多个三维对象,你可以把它理解成放置物体的容器

// 创建场景
const scene = new THREE.Scene();

场景对象还提供了一些方法和属性,用于控制场景的行为和外观。例如,可以设置场景的背景颜色、雾化效果等。

// 设置背景为黑色
scene.background = new THREE.Color(0x000000); 
// 创建雾化效果
scene.fog = new THREE.Fog(0xffffff, 100, 200);

相机Camera

three.js中相机是一个重要的组件,它决定了场景如何被观察。three.js支持多种相机类型,如透视相机(PerspectiveCamera)和正交相机(OrthographicCamera)。
在这里插入图片描述

相机位置.position

生活中用相机拍照,你相机位置不同,拍照结果也不同,threejs中虚拟相机同样如此。
比如有一间房子,你拿着相机站在房间里面,看到的是房间内部,站在房子外面看到的是房子外面效果。
相机对象Camera具有位置属性.position,通过位置属性.position可以设置相机的位置。

// 根据需要设置相机位置具体值
camera.position.set(200, 200, 200);

相机观察目标.lookAt()

你用相机拍照你需要控制相机的拍照目标,具体说相机镜头对准哪个物体或说哪个坐标。对于threejs相机而言,就是设置.lookAt()方法的参数,指定一个3D坐标。

//坐标原点
camera.lookAt(0, 0, 0);
// y轴上位置10
camera.lookAt(0, 10, 0);
// 指向mesh对应的位置
camera.lookAt(mesh.position);

在这里插入图片描述
如何判断相机相对于场景中长方体的位置?根据相机位置和长方体位置尺寸对比,判断两者相对位置。

// 长方体尺寸100, 100, 100
const geometry = new THREE.BoxGeometry( 100, 100, 100 );
const mesh = new THREE.Mesh(geometry, material);
// 网格模型位置xyz坐标
mesh.position.set(0,10,0);
// 相机位置xyz坐标
camera.position.set(200, 200, 200);

定义相机渲染输出画布尺寸

生活中相机拍照的照片是有大小的,对于threejs而言一样,需要定义相机在网页上输出的Canvas画布(照片)尺寸,大小可以根据需要定义。

const width = window.innerWidth; // canvas画布宽度
const height = window.innerHeight; // canvas画布高度

透视投影相机

透视投影相机PerspectiveCamera本质上就是在模拟人眼观察这个世界的规律。可调位置、角度等信息,展示不同画面。
在这里插入图片描述
透视投影相机的四个参数fov, aspect, near, far构成一个四棱台3D空间,被称为视锥体,只有视锥体之内的物体,才会渲染出来,视锥体范围之外的物体不会显示在Canvas画布上。

PerspectiveCamera( fov, aspect, near, far )
参数介绍
  • fov:相机视锥体竖直方向视野角度,默认值50。
  • aspect:相机视锥体水平方向和竖直方向长度比,一般设置为Canvas画布宽高比width / height,默认值1。
  • near:相机视锥体近裁截面相对相机距离,默认值0.1。
  • far:相机视锥体远裁截面相对相机距离,far-near构成了视锥体高度方向,默认值2000。
// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
const width = window.innerWidth; // canvas画布宽度
const height = window.innerHeight; // canvas画布高度
// 实例化一个透视投影相机对象 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);

注意:1. 相机位置拉远可以看到更大的观察范围。
2. 超出视锥体远裁界面的范围的会被剪裁掉。

正投影相机

在正投影相机的投影模式下,无论物体距离相机距离远或者近,在最终渲染的图片中物体的大小都保持不变。这意味着所有物体在渲染时保持相同的尺寸,不受距离的影响。对于渲染2D场景或者UI元素是非常有用的。
在这里插入图片描述
正投影相机的六个参数left, right, top, bottom, near, far构成一个长方体可视化空间,和透视投影相机PerspectiveCamera视锥体相似,只是形状不同,两者的区别是透视投影可以模拟人眼观察世界的视觉效果,正投影相机不会。

OrthographicCamera( left, right, top, bottom, near, far )
参数介绍
  • left:渲染空间的左边界。
  • right:渲染空间的右边界。
  • top:渲染空间的上边界。
  • bottom:渲染空间的下边界。
  • near:属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值,默认值0.1。
  • far:属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小小,会有部分场景看不到,默认值2000。
// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
const width = window.innerWidth; // canvas画布宽度
const height = window.innerHeight; // canvas画布高度
const k = width / height; // canvas画布宽高比
const s = 600; // 控制left, right, top, bottom范围大小
const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 8000);

相机参数更新

透视投影相机PerspectiveCamera.aspect属性受到canvas画布宽高度影响,当canvas画布尺寸发生变化的时候,需要更新透视投影相机的.aspect属性。

window.onresize = function () {
    // width、height表示canvas画布宽高度
    camera.aspect = width / height;
    // 相机的aspect属性变化了,通知threejs系统
    camera.updateProjectionMatrix();
};

正投影相机OrthographicCameraleftright属性受到canvas画布宽高比影响,所以需要随着canvas画布更新。

window.onresize = function () {
    // 更新相机参数
    const k = width / height; //canvas画布宽高比
    camera.left = -s*k;
    camera.right = s*k;
    // 相机的left, right, top, bottom属性变化了,通知threejs系统
    camera.updateProjectionMatrix();
};

相机选择

对于大部分需要模拟人眼观察效果的场景,需要使用透视投影相机,比如人在场景中漫游,或是在高处俯瞰整个园区或工厂。
正投影没有透视效果,也就是不会模拟人眼观察世界的效果。在一些不需要透视的场景你可以选择使用正投影相机,比如整体预览一个中国地图的效果,或者一个2D可视化的效果。

渲染器

生活中如果有了景物和相机,那么如果想获得一张照片,就需要你拿着相机,按一下,咔,完成拍照。对于threejs而言,如果完成“咔”这个拍照动作,就需要一个新的对象,也就是WebGL渲染器WebGLRenderer。

WebGL渲染器

// 创建渲染器对象
const renderer = new THREE.WebGLRenderer();

设置canvas画布尺寸.setSize

// 定义threejs输出画布的尺寸(单位:像素px)
const width = window.innerWidth; // canvas画布宽度
const height = window.innerHeight; // canvas画布高度
renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px)

渲染器渲染方法.render()

渲染器WebGLRenderer执行渲染方法.render()就可以生成一个Canvas画布(照片),并把三维场景Scene呈现在canvas画布上面,你可以把.render()理解为相机的拍照动作“咔”。

renderer.render(scene, camera); //执行渲染操作

渲染循环,更新场景渲染,根据当前计算机浏览器刷新帧率(默认 60 次/秒),不断递归调用此函数渲染最新的画面状态,当前页面切换到后台后暂停递归。

// 渲染循环
function render() {
    camera.position.z -= 0.3;//相机直线运动动画
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}
render();

渲染器Canvas画布属性.domElement

渲染器WebGLRenderer通过属性.domElement可以获得渲染方法.render()生成的Canvas画布,.domElement本质上就是一个HTML元素:Canvas画布。

document.body.appendChild(renderer.domElement);

可以把threejs的渲染结果renderer.domElement,插入到web页面上任何一个HTML元素中,只要符合你的项目布局规则即可。

<div id="canvas"></div>
document.getElementById('webgl').appendChild(renderer.domElement);

canvas画布宽高度动态变化

window.onresize = function () {
    // 重置渲染器输出画布canvas尺寸
    renderer.setSize(window.innerWidth, window.innerHeight);
};

渲染器其他属性设置

const renderer = new THREE.WebGLRenderer({
    antialias:true, // 锯齿属性
    alpha: true, // 背景透明
    preserveDrawingBuffer:true,//想把canvas画布上内容下载到本地
});

创建基础场景

// 创建场景
const scene = new THREE.Scene();
// 创建透视投影相机,视角45度,画幅比例 宽比高,近平面距离0.1,远平面1000
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
const width = window.innerWidth; // canvas画布宽度
const height = window.innerHeight; // canvas画布高度
// 渲染器canvas宽高设为与窗口一致
renderer.setSize(width, height);
// 将渲染器对应的dom元素添加到body中
document.body.appendChild(renderer.domElement);
// 移动相机位置
camera.position.set(0, 200, 300);
renderer.render(scene, camera);
  • 20
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值