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开发实战(第25课:路由与终结点:如何规划好你的Web API)--学习笔记(下)

    25 | 路由与终结点:如何规划好你的Web API 自定义约束实现了路由约束接口,它只有一个 Match 方法,这个方法传入了 Http 当前的 httpContext,route,routeKey ...

  2. 大数据生态组件WEB UI地址汇总

    (1) Hadoop Web UI http://master-1:50070/dfshealth.html#tab-overview (2) YARN应用Web UI http://master-1 ...

  3. Pandas—to_csv()写入函数参数详解

    1. to_csv函数的参数 DataFrame.to_csv(path_or_buf=None, sep=',', na_rep='', float_format=None, columns=Non ...

  4. Linux dmesg命令使用方法详解

    一.命令简介  dmesg(display message)命令用于显示开机信息.kernel 会将开机信息存储在 ring buffer 中.您若是开机时来不及查看信息,可利用 dmesg 来查看. ...

  5. Thinkpad笔记本指点杆(小红点)自动漂移的问题

    Dell, HP, Thinkpad在高端商务机上会配备指点杆(小红点), 有很多人是指点杆的忠实用户, 因为工作时可以双手不离键盘, 非常方便. 在指点杆的使用过程中, 有时候会遇到指点杆自己漂移的 ...

  6. 【Unity3D】基于模板测试和顶点膨胀的描边方法

    1 前言 ​ 选中物体描边特效 中介绍了基于模板纹理模糊膨胀的描边方法,该方法实现了软描边,效果较好,但是为了得到模糊纹理,对屏幕像素进行了多次渲染,效率欠佳.本文将介绍另一种描边方法:基于模板测试和 ...

  7. 一键部署Home Assistant ubuntu 20.4.3 树莓派3b+脚本

      树莓派3b+安装好 Ubuntu Server 20.04.3 LTS 32bit 后即可适用此脚本,其他版本树莓派/系统可能需要微调脚本*为方便一些未知/已知错误排查 脚本存在冗余部分,足够了解 ...

  8. windbg 分析 32 位进程的 64 位转储文件

    场景: x86 的项目在 x64 的 windows 机器上运行时出现未响应的情况,使用任务管理器创建该进程的转储文件 因为项目是 32 位的,所以使用 x86 的 windbg 来调试 dmp 文件 ...

  9. EnumColorProfiles WcsGetDefaultColorProfile WcsSetDefaultColorProfile的使用

    #include <Windows.h> #include <Icm.h> #include <iostream> #include <string> ...

  10. uber-go guide,uber的go编码规范

    uber-go guide,uber的go语言编码规范 感谢翻译者和原作们 本文转自:https://github.com/xxjwxc/uber_go_guide_cn (特此感谢作者的翻译,感谢他 ...