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 中,万物皆对象,为什么还要通过 ...
随机推荐
- podman安装mysql容器
前言 mysql如果正式安装,卸载起来比较麻烦.如果是自己测试用的话,可以用podman拉取一个镜像来使用. 这里使用的是mysql5.7版本,对应的docker镜像是mysql:5.7 (如果拉取较 ...
- python3 pip3 安装 xmlrpc 失败
python2 使用的是xmlrpclib库,到了 python3, 就直接使用 xmlrpc.client 和 xmlrpc.server了. 接下来,我使用 pip3 install xmlrpc ...
- 3款C#开源且实用的工具类库,工作效率提升利器!
前言 在日常工作开发中工具类库是软件开发中不可或缺的一部分,它们通过提供代码重用.通用功能.隐藏复杂性.提高代码质量.扩展性等方面的优势,帮助开发者更高效.更稳定地构建软件应用程序.今天大姚给大家分享 ...
- 如何应对红帽不再维护 CentOS
CentOS(Community Enterprise Operating System,社区企业操作系统)是一种开源的.免费的操作系统.由 Lance Davis 发起,通过社区驱动,目标是创建一个 ...
- c 语言学习第四天
if 语句 格式: // 1 // 其他语句... if(表达式){ // 其他语句... } // 其他语句... // 2 if(表达式){ }else{ } // 3 if(表达式1){ }el ...
- 妙趣横生:利用Echarts实现SpreadJS引用从属关系的可视化魅力
最新技术资源(建议收藏) https://www.grapecity.com.cn/resources/ 在金融行业,我们经常会有审计审查的需求,对某个计算结果进行审查,但是这个计算结果可能依赖多个单 ...
- Nuxt 使用指南:掌握 useNuxtApp 和运行时上下文
title: Nuxt 使用指南:掌握 useNuxtApp 和运行时上下文 date: 2024/7/21 updated: 2024/7/21 author: cmdragon excerpt: ...
- 那些血淋淋的教训——math
1. 方程的解要写 x= 2023.12.10 晚上周测填空题第 \(2\) 题,方程的解写成了 \(7\) 而不是 \(x=7\). 2. 分类讨论 选填的最后一题. 3. 去绝对值看清楚符号(某个 ...
- c++ 17 demo
1 // Cpp.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并结束. 2 // 3 4 #include <iostream> 5 #includ ...
- whk随记
金刚烷,实际上是p4把磷换成碳,然后在每两个碳之间再加一个碳,氢再补齐,由于碳都是sp3杂化,所以画出来并不对称,但实际上是对称的,一氯代物只有两种,像p4o6一样,而p4o10实际上是每个磷外面再连 ...