1. 引言

Three.js是著名的JavaScript 3D图形库,用于浏览器中开发 3D 交互场景的 JS 引擎,可以快速的搭建三维场景

Three.js官网为:创建一个场景 – three.js docs (threejs.org)

GitHub站点为:mrdoob/three.js: JavaScript 3D Library. (github.com)

本文描述Three.js的基础使用与搭建一个场景

2. 基础使用

2.1 基础场景

使用Three.js构建一个场景,大致步骤如下:

graph LR
材质Material --> Mesh
几何体Geometry --> Mesh --> 场景Scene --> 渲染器Renderer
相机Camera --> 渲染器Renderer

按照上述流程,简要设置几个参数,就可以构建出一个简单的场景:

<!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>
<style>
html,
body,
canvas {
height: 100%;
width: 100%;
margin: 0;
}
</style>
</head> <body>
<canvas id="canvas"></canvas>
<script type="module">
import * as THREE from 'https://cdn.bootcdn.net/ajax/libs/three.js/0.151.3/three.module.js'; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5; const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#canvas')
});
renderer.setSize(window.innerWidth, window.innerHeight, false) const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({
color: 0x00ff00
});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube); function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
</script>
</body> </html>

结果如下:

2.2 光照

添加光照并修改一下材质(使其可以反光):

graph LR
材质Material --> Mesh
几何体Geometry --> Mesh --> 场景Scene
光照Light --> 场景Scene --> 渲染器Renderer
相机Camera --> 渲染器Renderer
<!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>
<style>
html,
body,
canvas {
height: 100%;
width: 100%;
margin: 0;
}
</style>
</head> <body>
<canvas id="canvas"></canvas>
<script type="module">
import * as THREE from 'https://cdn.bootcdn.net/ajax/libs/three.js/0.151.3/three.module.js'; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5; const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#canvas')
});
renderer.setSize(window.innerWidth, window.innerHeight, false) const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshPhongMaterial({
color: 0x00ff00
});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube); const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(0, 0, 5);
scene.add(light); function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
</script>
</body> </html>

结果如下:

2.3 多个Mesh

添加两个Mesh到场景中,并共用一个Geometry:

graph LR
材质Material --> Mesh1
几何体Geometry --> Mesh1 --> 场景Scene
材质Material2 --> Mesh2
几何体Geometry --> Mesh2 --> 场景Scene
光照Light --> 场景Scene --> 渲染器Renderer
相机Camera --> 渲染器Renderer
<!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>
<style>
html,
body,
canvas {
height: 100%;
width: 100%;
margin: 0;
}
</style>
</head> <body>
<canvas id="canvas"></canvas>
<script type="module">
import * as THREE from 'https://cdn.bootcdn.net/ajax/libs/three.js/0.151.3/three.module.js'; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5; const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#canvas')
});
renderer.setSize(window.innerWidth, window.innerHeight, false) const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshPhongMaterial({
color: 0x00ff00
});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube); const material2 = new THREE.MeshPhongMaterial({
color: 0x0000ff
});
const cube2 = new THREE.Mesh(geometry, material2);
cube2.position.x = 2;
scene.add(cube2); const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(0, 0, 5);
scene.add(light); function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
</script>
</body> </html>

结果如下:

2.4 控制器

加入轨道控制器OrbitControls实现场景拖动:

graph LR
材质Material --> Mesh
几何体Geometry --> Mesh --> 场景Scene
光照Light --> 场景Scene --> 渲染器Renderer
相机Camera --> 渲染器Renderer
相机Camera --> 控制器Controls
<!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>
<style>
html,
body,
canvas {
height: 100%;
width: 100%;
margin: 0;
}
</style> </head> <body>
<canvas id="canvas"></canvas> <script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three/build/three.module.js",
"three/addons/": "https://unpkg.com/three/examples/jsm/"
}
}
</script> <script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; const scene = new THREE.Scene(); const canvas = document.querySelector('#canvas');
const camera = new THREE.PerspectiveCamera(75, canvas.clientWidth / canvas.clientHeight , 0.1, 1000);
camera.position.z = 5; const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#canvas')
});
renderer.setSize(window.innerWidth, window.innerHeight, false) const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshPhongMaterial({
color: 0x00ff00
});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube); const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(0, 0, 5);
scene.add(light); const controls = new OrbitControls( camera, renderer.domElement ); function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
</script>
</body> </html>
  • 注意这里的CDN地址、加载方式有变动

结果如下:

2.5 模型加载

加入GLTFLoader加载GLTF模型:

graph LR
材质Material --> Mesh
几何体Geometry --> Mesh --> 场景Scene
加载器Loader -->模型Model --> 场景Scene
光照Light --> 场景Scene --> 渲染器Renderer
相机Camera --> 渲染器Renderer
相机Camera --> 控制器Controls

模型下载自:three.js/Xbot.glb at dev · mrdoob/three.js · GitHub

<!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>
<style>
html,
body,
canvas {
height: 100%;
width: 100%;
margin: 0;
}
</style> </head> <body>
<canvas id="canvas"></canvas> <script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three/build/three.module.js",
"three/addons/": "https://unpkg.com/three/examples/jsm/"
}
}
</script> <script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; const scene = new THREE.Scene(); const canvas = document.querySelector('#canvas');
const camera = new THREE.PerspectiveCamera(75, canvas.clientWidth / canvas.clientHeight , 0.1, 1000);
camera.position.z = 5; const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#canvas')
});
renderer.setSize(window.innerWidth, window.innerHeight, false) const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshPhongMaterial({
color: 0x00ff00
});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube); const gltfLoader = new GLTFLoader();
gltfLoader.load('./models/Xbot.glb', (gltf) => {
scene.add(gltf.scene)
gltf.scene.position.z = 2
}) const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(0, 0, 5);
scene.add(light); const controls = new OrbitControls( camera, renderer.domElement ); function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
</script>
</body> </html>

结果如下:

3. 参考资料

[1] 创建一个场景 – three.js docs (threejs.org)

[2] mrdoob/three.js: JavaScript 3D Library. (github.com)

[3] three.js manual (threejs.org)

Three.js的基础使用的更多相关文章

  1. node.js学习(二)--Node.js控制台(REPL)&&Node.js的基础和语法

    1.1.2 Node.js控制台(REPL) Node.js也有自己的虚拟的运行环境:REPL. 我们可以使用它来执行任何的Node.js或者javascript代码.还可以引入模块和使用文件系统. ...

  2. Node.js系列基础学习----安装,实现Hello World, REPL

    Node.js基础学习 简介 简单的说 Node.js 就是运行在服务端的 JavaScript.Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台.Node.js是一 ...

  3. css+js+html基础知识总结

    css+js+html基础知识总结 一.CSS相关 1.css的盒子模型:IE盒子模型.标准W3C盒子模型: 2.CSS优先级机制: 选择器的优先权:!important>style(内联样式) ...

  4. JavaScript基础精华02(函数声明,arguments对象,匿名函数,JS面向对象基础)

    函数声明 JavaScript中声明函数的方式:(无需声明返回值类型) function add(i1, i2) {             return i1 + i2;//如果不写return返回 ...

  5. JavaScript--我发现,原来你是这样的JS(基础概念--灵魂篇,一起来学js吧)

    介绍 这是红宝书(JavaScript高级程序设计 3版)的读书笔记第三篇(灵魂篇介绍),有着剩下的第三章的知识内容,当然其中还有我个人的理解.红宝书这本书可以说是难啃的,要看完不容易,挺厚的,要看懂 ...

  6. js复习--基础

    最近工作遇到了一些小困难,基础真的很重要,漫天高楼起于地. 一,script元素 包括type=“text/Javascript”,defer延迟到html加载完解析,src=“../../test. ...

  7. 第八节 JS运动基础

    运动基础 让Div运动起来 速度——物体运动的快慢 运动中的Bug 不会停止 速度取某些值会无法停止 到达位置后再点击还会运动 重复点击速度加快 匀速运动(速度不变) 运动框架及应用: 运动框架: 在 ...

  8. JS零基础一步一步做应用全记录

    1.起因 作为几个外卖重度依赖癌晚期患者,呆宿舍的时候几个人一起叫外卖已经是常事.偶然看到隔壁宿舍在饿了么订餐的时候,看到在饿了么的首页上有一个谁去拿外卖的一个小游戏/工具,感觉这个小细节,饿了么把握 ...

  9. 认识JS的基础对象,定义对象的方法

    JS的基础对象: 1.window       //窗口对象 2.document   //文档对象 3.document.documentElement      //html对象 4.docume ...

  10. 贰、js的基础(一)

    1.js的语法 a.区分大小写 b.弱类型变量:变量无特定类型 c.每行结尾的分号可有可无 d.括号用于代码块 e.注释的方法与c语言和java相同 2.变量 注意事项: a.通过关键字var来声明. ...

随机推荐

  1. .NET Core开发实战(第2课:内容综述)--学习笔记

    02 | 内容综述 课程目标 掌握 .NET Core 微服务架构的最佳实践 成长为一个具备良好架构设计能力的架构师 课程内容 第一部分 .NET Core 的必备知识 第二部分 .NET Core ...

  2. 开源.NetCore通用工具库Xmtool使用连载 - 发送邮件篇

    [Github源码] <上一篇> 介绍了Xmtool工具库中的随机值类库,今天我们继续为大家介绍其中的邮件发送类库. 发送邮件是系统开发中经常需要的功能,广泛应用于消息通知.异常告警.内容 ...

  3. NC208250 牛牛的最美味和最不美味的零食

    题目链接 题目 题目描述 牛牛为了减(吃)肥(好),希望对他的零食序列有更深刻的了解,所以他把他的零食排成一列,然后对每一个零食的美味程度都打了分,现在他有可能执行两种操作: eat k:吃掉当前的第 ...

  4. Sora文生视频模型深度剖析:全网独家指南,洞悉98%关键信息,纯干货

    Sora文生视频模型深度剖析:全网独家指南,洞悉98%关键信息,纯干货 Sora是一个以视频生成为核心的多能力模型,具备以下能力: 文/图生成视频 视频生成视频 1分钟超长高质量视频生成 视频裂变多视 ...

  5. 【Unity3D】基于AssetBundle实现资源热更新

    1 前言 ​ Unity3D 本地资源一般放在 Resources 目录下,但是 Resouces 文件夹的大小不能超过 2G,使用 AssetBundle 管理资源可以解决 Resources 文件 ...

  6. Java定时器(Timer)

    1.介绍 Timer和TimerTask是用于在后台线程中调度任务的java util类.简单地说,TimerTask是要执行的任务,Timer是调度器. 2.调度一次性任务 2.1 指定延迟后执行 ...

  7. Java中的包装类(wrapper class)

    1.介绍 顾名思义,包装类是封装Java原始类型的对象.每个Java原始类型都有一个对应的包装类: 基本类型 包装类 boolean Boolean byte Byte short Short cha ...

  8. P1481魔族密码 题解(字典树)

    魔族密码 题目背景 风之子刚走进他的考场,就-- 花花:当当当当~~偶是魅力女皇--花花!!^^(华丽出场,礼炮,鲜花) 风之子:我呕--(杀死人的眼神)快说题目!否则---_-### 题目描述 花花 ...

  9. Acrobat 教程

    https://helpx.adobe.com/cn/acrobat/using/pdf-form-field-properties.html

  10. 迁移到 Gradle 7.x 使用 Version Catalogs 管理依赖

    一.根目录下 build.gradle 变更 变更前: buildscript { ext.kotlin_version = '1.5.0' repository { repository { mav ...