如果你曾经想用JavaScript构建一个游戏,你可能会使用Three.js.。

Three.js 是一个我们可以用来在浏览器中渲染 3D 图形的库。整个操作都在 JavaScript 中,所以通过一些逻辑,您可以添加动画、交互,甚至将其变成游戏。

在本教程中,我们使用Three.js的基础知识,实现一个非常简单的示例。我们将渲染一个 3D 盒子。

Three.js 在后台使用 WebGL 来渲染 3D 图形。我们可以使用普通的 WebGL,但它非常复杂且级别较低。另一方面,Three.js 就像在玩乐高积木。

一、创建项目

创建一个目录box-demo,并在里面创建index.html和script.js文件。

要想使用Three.js,需要安装它。或者是引入。

这里我们引入即可:

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r126/three.min.js"> </script>

index.html页面内容如下:

<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>demo</title></head><body><script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r126/three.min.js"> </script><script src="script.js"></script></body></html>

二、代码实现

在本文中,我们将介绍如何在场景中放置 3D 对象、设置照明和相机,以及在画布上渲染场景。那么让我们看看我们如何做到这一切。

2.1 定义场景对象

首先,我们必须定义一个场景。这将是一个放置 3D 对象和灯光的容器。场景对象也有一些属性,比如背景颜色。设置是可选的。如果我们不设置它,则默认为黑色。


// 1.创建场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000); // 可选的, 默认黑色

2.2 Geometry + Material = Mesh

几何+材质=网格

然后我们将3D长方体作为网格添加到场景中。网格是几何体和材质的组合。

// 2. 添加一个立方体盒子
// 几何形体
const geometry = new THREE.BoxGeometry(3, 1, 3); // width, height, depth
// 材质
const material = new THREE.MeshLambertMaterial({ color: 0xfb8e00 });
// 网格
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 0, 0); // 可选的, 默认位置0,0,0
scene.add(mesh);

1、什么是几何?

几何图形是我们正在构建的渲染形状 - 就像一个盒子。可以从顶点构建几何图形,也可以使用预定义的几何图形。

BoxGeometry 是最基本的预定义选项。我们只需要设置盒子的宽度、高度和深度就可以了。

你可能会认为我们通过定义盒子来操作会不方便,但许多极简设计的游戏只使用盒子的组合。

还有其他预定义的几何形状。我们可以很容易地定义一个平面、一个圆柱体、一个球体,甚至是一个二十面体。

2、如何使用材料

然后我们定义一个材质。材质描述了物体的外观。在这里,我们可以定义诸如纹理、颜色或不透明度之类的东西。

在这个例子中,我们只设置一种颜色。材料仍然有不同的选择。它们中的大多数之间的主要区别在于它们对光的反应。

最简单的是MeshBasicMaterial。这种材料根本不关心光线,每一面都会有相同的颜色。不过,这可能不是最佳选择,因为您看不到盒子的边缘。

关心光的最简单的材料是 MeshLambertMaterial。这将计算每个顶点的颜色,实际上是每一边。但它并不止于此。

如果您需要更高的精度,还有更高级的材料。MeshPhongMaterial 不仅按顶点计算颜色,而且按每个像素计算颜色。颜色可以在一侧改变。这有助于提高现实主义,但也会降低性能成本。

它是否有实际的效果,还取决于灯光设置和几何形状。如果我们渲染盒子并使用定向光,结果不会有太大变化。但是如果我们渲染一个球体,区别就更明显了。

3、如何定位网格

一旦我们有了一个网格,我们还可以将它定位在场景中并设置每个轴的旋转。稍后,如果我们想在 3D 空间中为对象设置动画,我们将主要调整这些值。

对于定位,我们使用与设置大小相同的单位。无论您使用的是小数还是大数,您只需要在自己的整个项目中保持一致即可。

对于旋转,我们以弧度设置值。因此,如果您的值以度为单位,则必须将它们除以 180°,然后乘以 PI。

2.3 如何添加灯光

然后让我们添加灯光。具有基本材质的网格不需要任何灯光,因为无论灯光设置如何,网格都将具有设定的颜色。

但是 Lambert 材料和 Phong 材料需要光。如果没有任何光,网格将保持在黑暗中。


// 3. 设置环境光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); // 颜色,强度0-1
scene.add(ambientLight);

我们将添加两盏灯——一个环境光和一个定向光。

首先,我们添加环境光。环境光从各个方向照射,为我们的几何体提供了基础颜色。

要设置环境光,我们设置颜色和强度。颜色通常为白色,但您可以设置任何颜色。强度是一个介于 0 和 1 之间的数字。我们定义的两个灯以累积的方式工作,因此在这种情况下,我们希望每个灯的强度约为 0.5。

定向灯具有类似的设置,但它也有一个位置。这里的位置这个词有点误导,因为它并不意味着光来自一个确切的位置。

定向光从很远的地方发出,许多平行光线都具有固定的角度。但我们不是定义角度,而是定义单个光线的方向。

在这种情况下,它从 10,20,0 位置的方向向 0,0,0 坐标照射。但当然,定向光不仅仅是一条光线,而是无限量的平行光线。

把它想象成太阳。在较小的尺度上,太阳的光线也平行下降,太阳的位置并不重要,重要的是它的方向。

这就是定向光的作用。它用来自很远的平行光线照射在一切事物上。


// 添加定向光
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight.position.set(10, 20, 0); // x, y, z
scene.add(directionalLight);

在这里,我们将光的位置设置为从上方(使用 Y 值)并沿 X 轴移动一点。Y 轴具有最高值。这意味着盒子的顶部接收到的光线最多,它将是盒子最闪亮的一面。

光线也沿着 X 轴移动了一点,所以盒子的右侧也会收到一些光线,但会少一些。

并且因为我们没有沿 Z 轴移动光源位置,所以盒子的正面将不会接收到任何来自该光源的光线。如果没有环境光,正面将保持黑暗。

还有其他的灯类型。例如,PointLight 可用于模拟灯泡。它有一个固定的位置,它向各个方向发光。SpotLight 可以用来模拟汽车的聚光灯。它从一个点向沿着圆锥的方向发射光。

2.4 如何设置相机

到目前为止,我们已经创建了一个包含几何体和材质的网格。我们还设置了灯光并添加到场景中。我们仍然需要一个相机来定义我们如何看待这个场景。

这里有两种选择:透视相机( perspective cameras ) 和正交相机 ( orthographic cameras )。

电子游戏大多使用透视相机,因为它们的工作方式与您在现实生活中的观察方式相似。更远的东西看起来更小,而你面前的东西看起来更大。

使用正交投影,无论物体离相机多远,它们都将具有相同的大小。正交相机具有更简约的几何外观。它们不会扭曲几何图形,平行线将平行出现。

对于这两个相机,我们必须定义一个视锥体。这是 3D 空间中将被投影到屏幕上的区域。此区域之外的任何内容都不会出现在屏幕上。这是因为它要么太近要么太远,或者因为相机没有指向它。

使用透视投影,视锥体中的所有内容都以直线投影到视点。距离相机较远的东西在屏幕上显得更小,因为从视点看,您可以在更小的角度看到它们。


// 4. 设置相机
const aspect = window.innerWidth / window.innerHeight;
const camera = new THREE.PerspectiveCamera(45, // 摄像机视锥体垂直视野角度aspect, // 摄像机视锥体长宽比1, // 摄像机视锥体近端面100 // 摄像机视锥体远端面
);camera.position.set(4, 4, 4);
camera.lookAt(0, 0, 0);

要定义透视摄影机,需要设置视野,即与视点的垂直角度。然后定义框架宽度和高度的纵横比。

然后,最后两个参数定义了近平面和远平面距离视点的距离。太靠近相机的东西会被忽略,太远的东西也会被忽略。

...// Orthographic camera
const width = 10;
const height = width * (window.innerHeight / window.innerWidth);
const camera = new THREE.OrthographicCamera(width / -2, // leftwidth / 2, // rightheight / 2, // topheight / -2, // bottom1, // near100 // far
);...

然后是正交相机。在这里,我们不是将事物投射到一个点上,而是投射到一个表面上。每条投影线是平行的。这就是为什么物体离相机有多远并不重要,这就是它不会扭曲几何形状的原因。

对于正交相机,我们必须定义每个平面与视点的距离。左平面因此向左五个单位,右平面向右五个单位,依此类推。

...camera.position.set(4, 4, 4);
camera.lookAt(0, 0, 0);...

无论我们使用哪个相机,我们还需要定位它并设置它的方向。如果我们使用的是正交相机,那么这里的实际数字并不重要。无论对象离相机多远,它们都将显示相同的大小。不过,重要的是它们的比例。

通过整个教程,我们通过同一个摄像头看到了所有示例。该相机沿每个轴移动相同的单位,并朝向 0,0,0 坐标。定位正交相机就像定位定向光。重要的不是实际位置,而是方向。

2.5 如何渲染场景

所以我们设法把场景和相机放在一起。现在只缺少将图像渲染到我们的浏览器中的最后一块。

我们需要定义一个 WebGLRenderer。当我们提供场景和相机时,它能够将实际图像渲染到 HTML 画布中。这也是我们可以设置此画布的实际大小的地方 - 画布的宽度和高度(以像素为单位),因为它应该出现在浏览器中。


// 渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true }); // 是否执行抗锯齿。默认为false.
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);

如下是全部代码:


// 1. 创建场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000); // 可选的, 默认黑色// 2. 添加一个立方体盒子
// 几何形体
const geometry = new THREE.BoxGeometry(3, 1, 3); // width, height, depth
// const geometry = new THREE.PlaneGeometry(3, 3); // 平面缓冲几何体(PlaneGeometry)
// const geometry = new THREE.CylinderGeometry(1.5, 3, 2, 32); // 圆柱缓冲几何体(CylinderGeometry)顶部半径,底部半径,高度,分段数
// const geometry = new THREE.SphereGeometry(1.5, 32, 32); // 球缓冲几何体(SphereGeometry)半径,水平分段数,垂直分段数
// 。。。。// 材质
const material = new THREE.MeshLambertMaterial({ color: 0xfb8e00 });
// 网格
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 0, 0); // 可选的, 默认位置0,0,0
mesh.rotation.set(0, (90 / 180) * Math.PI, 0); // 对于旋转,我们以弧度设置值。因此,如果您的值以度为单位,则必须将它们除以 180°,然后乘以 PI。
scene.add(mesh);// 3. 设置环境光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); // 颜色,强度0-1
scene.add(ambientLight);// // 添加定向光
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight.position.set(10, 20, 0); // x, y, z
scene.add(directionalLight);// const light = new THREE.PointLight(0x00ff00, 1, 10);
// light.position.set(5, 0, 5); // x, y, z
// scene.add(light);// 4. 设置相机
const aspect = window.innerWidth / window.innerHeight;
const camera = new THREE.PerspectiveCamera(45, // 摄像机视锥体垂直视野角度aspect, // 摄像机视锥体长宽比1, // 摄像机视锥体近端面100 // 摄像机视锥体远端面
);// Orthographic camera
// const width = 10;
// const height = width * (window.innerHeight / window.innerWidth);
// const camera = new THREE.OrthographicCamera(
//  width / -2, // left
//  width / 2, // right
//  height / 2, // top
//  height / -2, // bottom
//  1, // near
//  100 // far
// );camera.position.set(4, 4, 4);
camera.lookAt(0, 0, 0);// 渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true }); //是否执行抗锯齿。默认为false.
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);// 添加到页面
document.body.appendChild(renderer.domElement);

最后,这里的最后一行将这个渲染的画布添加到我们的 HTML 文档中。这就是渲染盒子所需的全部内容。仅仅一个盒子可能看起来有点太多了,但大多数这些东西我们只需要设置一次。

三、运行

这里我们使用live-server。安装live-server后,在终端执行live-server命令后:

然后浏览器打开8080端口:

浏览器中渲染3D对象相关推荐

  1. 使用ThreeJS在浏览器中展示3D物件

    这是一篇介绍如何在浏览器中展示洗面奶3D物件的文章. 前言 这篇文章仅仅是向你介绍应对下面这种的场景的方法:如果有人突然跟你说,你的皮肤挺不错的耶,你用的什么洗面奶,我也想买一个,你会怎么回答呢?手头 ...

  2. 浏览器中实现3D全景浏览

    全景图共分为三种: ①球面全景图    利用一张全景图围成一个球,自身位置位于球体内.由于图片是矩形,所以最上和最下的缝合处很明显就能够看得出来.    球面全景图是最接近人眼的构建模式,若利用多个立 ...

  3. 活动报名丨英伟达AI Lab科学家、GET3D一作高俊:从图像中学习3D对象的生成建模...

    12月12日(周一)上午9:00「青源Live第57期丨英伟达AI Lab科学家.GET3D一作高俊:从图像中学习3D对象的生成建模」将在线举办,多伦多大学博士生.英伟达AI Lab研究科学家高俊做报 ...

  4. 绒毛动物探测器:通过TensorFlow.js中的迁移学习识别浏览器中的自定义对象

    目录 起点 MobileNet v1体系结构上的迁移学习 修改模型 训练新模式 运行物体识别 终点线 下一步是什么?我们可以检测到脸部吗? 下载TensorFlowJS-Examples-master ...

  5. 删除 Windows10系统 “此电脑” 中的 “3D对象” 等文件夹

    这篇文章将教会你在 Win10 下如何隐藏与恢复 "此电脑" 窗口中的 "3D 对象" 等文件夹,以及资源管理器侧栏中与之对应的快捷入口.由于 "3D ...

  6. 浏览器渲染类型2d 3d_Google在浏览器中提供3D渲染

    浏览器渲染类型2d 3d Google has released a new experimental browser plugin that makes it possible to display ...

  7. 【学堂上新】Unity UGUI 渲染 3D 对象详解

    UI界面中3D 对象的渲染,是游戏制作开发中的常见应用,看似简单,却隐藏许多的问题,比如渲染颜色的混合.遮盖关系.区域的裁剪.相机后效的处理--本文从两种常见的渲染方案入手,对常见问题进行分析,给出合 ...

  8. 删除“此电脑中”和“另存为中”的3D对象等七个文件夹

    如果要删除这七个文件夹,我们只需要右键点击桌面左下角的开始按钮,在弹出菜单中选择"运行"菜单项. 在打开的Windows10运行窗口中,我们输入命令regedit,然后点击确定按钮 ...

  9. 删除和恢复Win10文件管理器中的3D对象/音乐/视频/下载/文档等文件夹

    本文介绍:1.此电脑"视频.图片.文档.下载.音乐.桌面.3D 对象"六个文件夹快速删除.                  2.此电脑"视频.图片.文档.下载.音乐.桌 ...

最新文章

  1. 断点续传了解一下啊?
  2. 青岛智能物联网产才融合中心成立,山东大学携手百度飞桨海尔海纳云等共育AI人才
  3. eclipse User Enties 顺序
  4. 获取浏览器的可视区域尺寸
  5. Android系统的体系结构、开发语言及源码结构
  6. 科目三场外考试易出错的环节
  7. Hadoop解决内存受限问题
  8. arduino ps2摇杆程序_PS2手柄在arduino上进行测试,可用,供喜欢diy的朋友借鉴
  9. 美赛论文Latex模板说明
  10. 《自然语言处理实战入门》---- 停用词 知多少?
  11. 成都公办计算机学校,成都计算机学校公立-成都公立的计算机学校有哪
  12. FOXIT PDF SDK 8.1 ALL Crack
  13. 微信公众号菜单html5,微信公众号自定义菜单全攻略
  14. 80286保护模式和实模式的基础概念
  15. 计算机启动黑屏时间很长,电脑开机黑屏时间长怎么办?[多图]
  16. 计算机卡住了怎样恢复,电脑频繁假死怎么办 电脑死机数据恢复
  17. 服务器正文15:Assert的使用技巧
  18. 让div中的p标签文字垂直居中的方法
  19. 简易交通灯控制电路设计
  20. php公众号向多个用户推送消息,如何实现微信公众号给指定互动用户推送多次消息?...

热门文章

  1. java tomcat环境变量配置_JDK 和 tomcat 环境变量配置
  2. C++ 使用folly的异步回调功能时出现的错误处理
  3. 利用bat获取windows桌面壁纸
  4. css鼠标样式cursor介绍(鼠标手型)
  5. nodejs怎么看安装成功_淘宝特价版助力成功怎么查在哪看 淘宝特价版助力成功截图...
  6. Android 解决65536,统统给你解决
  7. 少儿编程教育方兴未艾,游戏化能打破僵局吗?
  8. 女神节,买什么礼物可以保护眼睛?保护眼睛的护眼台灯分享
  9. 如何在 Excel 中快速将多列数据合并到一列?(不同方法实现)前提不覆盖
  10. 用好PowerPoint的“重用幻灯片”