three.js的使用
以创建一个立方体为例

安装
安装three:npm i three

使用
引用
引入three以及three中自带的相机控件OrbitControls用以操控相机:

初始化场景
scene:场景所有three事物均在其中。
camera:使用PerspectiveCamera透视相机,参数需注意调整否则会看不见物体与场景,参数依次为:fov视场,即可看到的角度范围,aspect长宽比,通常为窗口长宽比,near近面,基于相机位置开始渲染场景的位置一般较小默认0.1,far远面,基于相机位置结束渲染场景的位置,过大会影响渲染效率默认1000。
renderer:渲染器,用于生成canvas及设置其参数,需要将其appendChild至dom中指定元素。

天空盒子
创建天空盒子(一个包裹场景物体的立方体,可随鼠标拖动而变化角度),其中六张立方体贴图对应的顺序是右、左、上、下、前、后,图片需是特别制作的全景图,否者场景世界会出现明显的拼接边角:

也可直接使用一张贴图作为场景的背景,但使用此法场景不会随着鼠标变换角度与缩放:

相机控件
创建相机控件,其中需将相机与渲染的canvas元素添加到控件OrbitControls中,可通过控件控制拖拽、缩放、阻尼、偏角、自转(此种自转方式区别于模型自转,模型自转是通过控制物体mesh的rotation实现自转,该文章使用的是模型自转)等:

光源
创建光源,可设置环境光、点光源,最终显示出的光影效果是通过各种光效一起计算后渲染出来的:

立方体
创建的mesh(可理解为创建的物体)都是要通过add添加到场景中的,而mesh中有geometry(几何体)与material(材质),立方体的geometry可以利用three的BoxGeometry,而material可以使用MeshLambertMaterial材质,该材质对光照有反应,用于创建暗淡的不发光的物体,自身可设置颜色,自身颜色不受环境的影响。也可给材质设置纹理map(需导入图片作为纹理):

持续渲染
对场景与相机进行持续渲染,其中requestAnimationFrame为请求动画帧,以60hz刷新(但在高刷新屏中会频繁触发),用户切换标签时会暂停渲染,节省cpu开销。鼠标控件需要在渲染中调用update()更新:

完整代码
点击查看代码
<template>
<div class="three-div">
<div id="container">
<!--画布的容器-->
</div>
</div>
</template>
<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; //鼠标控制
import cubeImg from "@/assets/img/cube.png";
import BgImg from "@/assets/img/bg.png";
import right from "@/assets/img/space/right.jpg";
import left from "@/assets/img/space/left.jpg";
import top from "@/assets/img/space/top.jpg";
import bottom from "@/assets/img/space/bottom.jpg";
import front from "@/assets/img/space/front.jpg";
import back from "@/assets/img/space/back.jpg";
export default {
components: {},
data() {
return {
scene: "", //场景
camera: "", //相机
renderer: "", //渲染器
mouseControls: "", //轨道控制
pointLight: "", //点光源
ambientLight: "", //环境光
cube: "", //立方体
cubeImg: cubeImg, //立方体贴图
};
},
mounted() {
this.init();
},
methods: {
//初始化场景
init() {
this.scene = new THREE.Scene(); //新建场景
let width = window.innerWidth; //窗口宽度
let height = window.innerHeight; //窗口高度
let k = width / height; //窗口宽高比
this.camera = new THREE.PerspectiveCamera(60, k, 0.1, 10); //透视相机
this.camera.position.set(0, 0, 2.5); //设置相机位置
//创建渲染器
this.renderer = new THREE.WebGLRenderer({
antialias: true, //抗锯齿
alpha: true,
});
this.renderer.setSize(width, height); //设置渲染区域尺寸
document
.getElementById("container")
.appendChild(this.renderer.domElement); //将画布添加到container中
let axes = new THREE.AxesHelper(1); //坐标系(辅助开发)
axes.rotation.x = 0.1;
// this.scene.add(axes);
this.createSkyBox();
// this.createUniverse();
this.createOrbitControls();
this.createLight();
this.createCube();
this.repeatRender();
},
//创建天空盒子
createSkyBox() {
//加载天空盒子纹理
let cubeTexture = new THREE.CubeTextureLoader().load(
[right,left,top,bottom,front,back]
);
this.scene.background = cubeTexture; //设置场景背景
},
//创建宇宙背景
createUniverse(){
let texture = new THREE.TextureLoader().load(BgImg);//加载背景贴图
this.scene.background = texture;//设置场景背景
},
//创建轨道控制
createOrbitControls() {
//没有缩放阻尼
this.mouseControls = new OrbitControls(
this.camera,
this.renderer.domElement
); //创建控件对象
this.mouseControls.enablePan = false; //右键平移拖拽
this.mouseControls.enableZoom = true; //鼠标缩放
this.mouseControls.minDistance = 2; //相机距离原点的距离范围
this.mouseControls.maxDistance = 5;
this.mouseControls.enableDamping = true; //滑动阻尼
this.mouseControls.dampingFactor = 0.1; //(默认.25)
this.mouseControls.maxPolarAngle = (Math.PI / 4) * 3; //y旋转角度范围
this.mouseControls.minPolarAngle = Math.PI / 4;
// this.mouseControls.autoRotate = true; //自转(相机)
// this.mouseControls.autoRotateSpeed = 5; //自转速度
},
//创建光源
createLight() {
this.ambientLight = new THREE.AmbientLight(0x666666); //设置环境光
this.scene.add(this.ambientLight); //将环境光添加到场景中
this.pointLight = new THREE.PointLight(0xffffff, 1, 0);
this.pointLight.position.set(200, 200, 200); //设置点光源位置
this.scene.add(this.pointLight); //将点光源添加至场景
},
//创建立方体
createCube() {
let geometry = new THREE.BoxGeometry(1, 1, 1); //几何体
//材质
let material = new THREE.MeshLambertMaterial({
map: new THREE.TextureLoader().load(this.cubeImg), //导入图片纹理
});
this.cube = new THREE.Mesh(geometry, material); //将几何体与材质添加到网格中
this.cube.rotation.set(10, 10, 0);
this.scene.add(this.cube); //将立方体网格添加到场景中
},
//重复渲染
repeatRender() {
//请求动画帧,屏幕每刷新一次调用一次,绑定屏幕刷新频率
requestAnimationFrame(this.repeatRender);
this.mouseControls.update(); //实时更新轨道控制
this.cube.rotation.y += .01;//以y为轴心的旋转角度每帧自加0.01
this.renderer.render(this.scene, this.camera); //将场景和相机进行渲染
},
},
};
</script>
<style scoped>
</style>
图片素材
天空盒子贴图
back.jpg:

bottom.jpg:

front.jpg:

left.jpg:

right.jpg:

top.jpg:

立方体贴图
cube.png:

three.js的使用的更多相关文章
- Vue.js 和 MVVM 小细节
MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自 ...
- js学习笔记:操作iframe
iframe可以说是比较老得话题了,而且网上也基本上在说少用iframe,其原因大致为:堵塞页面加载.安全问题.兼容性问题.搜索引擎抓取不到等等,不过相对于这些缺点,iframe的优点更牛,跨域请求. ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- JS调用Android、Ios原生控件
在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时, ...
- jquery和Js的区别和基础操作
jqery的语法和js的语法一样,算是把js升级了一下,这两种语法可以一起使用,只不过是用jqery更加方便 一个页面想要使用jqery的话,先要引入一下jqery包,jqery包从网上下一个就可以, ...
- 利用snowfall.jquery.js实现爱心满屏飞
小颖在上一篇一步一步教你用CSS画爱心中已经分享一种画爱心的方法,这次再分享一种方法用css画爱心,并利用snowfall.jquery.js实现爱心满屏飞的效果. 第一步: 利用伪元素before和 ...
- node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理
一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...
- JS正则表达式常用总结
正则表达式的创建 JS正则表达式的创建有两种方式: new RegExp() 和 直接字面量. //使用RegExp对象创建 var regObj = new RegExp("(^\\s+) ...
- 干货分享:让你分分钟学会 JS 闭包
闭包,是 Javascript 比较重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,很难从定义去理解它.因此,本文不会对闭包的概念进行大篇幅描述 ...
- JS核心系列:理解 new 的运行机制
和其他高级语言一样 javascript 中也有 new 运算符,我们知道 new 运算符是用来实例化一个类,从而在内存中分配一个实例对象. 但在 javascript 中,万物皆对象,为什么还要通过 ...
随机推荐
- python3 模型日记
说明 作为一种 python 框架模型的记录吧,用于个人总结,不定时更新. 正文 1. 主进程退出后,子进程也跟着退出 之前遇到过一种情况,用 flet 写了一个页面,然后又同时开了一个 tcp se ...
- 羊城杯初赛部分misc
羊城杯初赛部分misc Ez_misc i春秋刚考过的CVE,win11截图漏洞CVE-2023-21036(acropalypse) https://github.com/frankthetank- ...
- Oracle 存储过程 捕获异常
1.带参数插入并带返回值,异常信息 CREATE OR REPLACE PROCEDURE test_pro (v_id in int,v_name in varchar2,app_code out ...
- VirtualBox中Ubuntu 22.04 Server支持kvm
kvm简介 KVM 是 Kernel-based Virtual Machine 的缩写,是一种用于虚拟化的开源硬件虚拟化技术. 使用 Linux 内核的虚拟化模块,将物理服务器划分为多个虚拟机. K ...
- [oeasy]python0128_unicode_字符集_character_set_八卦_星座
unicode 回忆上次内容 中国的简体和繁体汉字 字符数量都超级大 彼此还认对方为乱码 如果有一种编码所有的字符都能编进去就好了 中日韩(CJK) 欧洲拼音 梵文 阿拉伯文 卢恩字符 等等等都包 ...
- 调试 Node.js
调试 Node.js 调试器 调试器是一种软件工具,用于通过分析方法观察和控制程序的执行流 设计目标:帮助找出 bug 的根本原因,并帮助你解决它 工作方式:将程序托管在自己的执行进程中或者作为附加到 ...
- 搭建lnmp环境-php(第二步)
系统环境:centos7 php7.4 编译安装太繁琐,这里用yum安装即可 ===========yum形式安装======== # 安装EPEL源(nginx那里已安装了,跳过) yum inst ...
- ThinkPHP6支持金仓数据库(Kingbase)解决无法使用模型查询问题
参考了很多前人的文章,最后只支持Db::query原生查询,不支持thinkphp数据模型方法,这在实际项目中是很难接受的,特分享出解决方案. 先按照流程配置如下: 1.准备工作 首先确认PHP支持金 ...
- 轻松搞定 Nginx 在 CentOS 和 Ubuntu 上的安装与配置
注:这是对我以前博客进行优化后再次发布的,博客中的截图为以前的.原博客已删除. 如何安装nginx nginx是一款开源.高性能的Web和反向代理服务器,支持HTTP.HTTPS.SMTP.POP3和 ...
- 虚拟硬盘系统 —— Windows系统 磁盘加速软件 —— 优缺点以及与真实物理磁盘访问文件的区别
在家里的局域网搞了一个NAS,但是由于磁盘读存速率问题导致远程copy的速度只有15MB/s,而如果NAS中的文件已在内存中有缓存则远程copy的速度为50MB/s. 于是考虑利用内存建立虚拟硬盘: ...