0

0

基础入门:使用Three.js进行WebGL开发

WBOY

WBOY

发布时间:2023-08-30 13:25:05

|

1852人浏览过

|

来源于php中文网

原创

浏览器中的 3d 图形自首次推出以来一直是一个热门话题。但如果您要使用纯 webgl 创建应用程序,则需要很长时间。这正是最近出现一些真正有用的库的原因。 three.js 是最受欢迎的之一,在本系列中,我将向您展示如何最好地使用它,以便为您的用户创建令人惊叹的 3d 体验。

在开始之前,我确实希望您在开始阅读本教程之前对 3D 空间有基本的了解,因为我不会解释坐标、向量等内容。


第 1 步: 准备工作

首先,创建三个文件:index.htmlmain.jsstyle.css。现在,下载 Three.js(带有示例和源代码的整个 zip 文件,或者单独的 JavaScript 文件,您可以选择)。现在,打开 index.html 并插入以下代码:




	
	


	


这就是您在此文件中所需要的全部内容。只是脚本和样式表的声明。所有的魔力都将发生在 main.js 中,但在我们实现这一点之前,我们还需要一个技巧来让应用程序看起来更好。打开 style.css 并插入以下代码:

canvas {
	position: fixed;
	top: 0;
	left: 0;
}

这会将画布定位在左上角,因为默认情况下 body 将具有 8px 的边距。现在我们可以继续处理 JavaScript 代码。


第 2 步:场景和渲染器

Three.js 使用显示列表的概念。这意味着所有对象都存储在列表中,然后绘制到屏幕上。

Three.js 使用显示列表的概念。这意味着所有对象都存储在列表中,然后绘制到屏幕上。在这里,这是一个 THREE.Scene 对象。您需要将想要在屏幕上绘制的任何对象添加到场景中。您可以拥有任意多个场景,但一个渲染器一次只能绘制一个场景(当然您可以切换显示的场景)。

渲染器只是将场景中的所有内容绘制到 WebGL 画布上。 Three.js 还支持在 SVG 或 2D Canvas 上绘图,但我们将重点关注 WebGL。

首先,让我们将窗口的宽度和高度存储在变量中,稍后我们将使用它:

var width = window.innerWidth;
var height = window.innerHeight;

现在定义渲染器和场景:

var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);

var scene = new THREE.Scene;

第一行定义 WebGL 渲染器。您可以将第一个参数中的渲染器选项作为地图传递。这里,我们将 antialias 设置为 true,因为我们希望对象的边缘平滑,而不是锯齿状。

第二行将渲染器大小设置为窗口的大小,在第三行中,我们将渲染器的 canvas 元素添加到文档中(您也可以使用库来执行此操作,例如 jQuery: $( 'body').append(renderer.domElement))。

最后一个定义场景,不需要参数。


第 3 步: 立方体

现在让我们添加要绘制的内容。让它成为一个立方体,因为它是最简单的 3D 对象。在 Three.js 中,屏幕上绘制的对象称为网格。每个网格都必须有自己的几何形状和材料。几何是一组需要连接才能创建对象的点。材质只是覆盖对象的油漆(或绘画,但这不是本教程的主题)。那么,让我们创建我们的立方体。幸运的是,Three.js 中有一些用于创建基元(简单形状)的辅助函数:

var cubeGeometry = new THREE.CubeGeometry(100, 100, 100);
var cubeMaterial = new THREE.MeshLambertMaterial({ color: 0x1ec876 });
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

cube.rotation.y = Math.PI * 45 / 180;

scene.add(cube);

如您所见,首先我们创建几何图形。参数定义立方体的大小:宽度、高度和深度。

接下来,我们定义立方体的材质。 Three.js中有一些材质类型,但是这次我们将使用THREE.MeshLambertMaterial,因为我们稍后想要一些光照(该材质使用兰伯特算法进行光照计算)。您可以将第一个参数中的选项作为映射传递,与渲染器相同 - 这几乎是 Three.js 中更复杂对象的规则。在这里,我们只使用颜色,它以十六进制数字形式传递。

在第三行,我们使用之前创建的几何体和材质创建一个网格。接下来,我们将立方体在 Y 轴上旋转 45 度,使其看起来更好。我们必须将度数更改为弧度,这是通过您可能记得的高中物理课上的方程式来处理的:Math.PI * 45 / 180。最后,立方体被添加到场景中。

现在您可以在浏览器中打开 index.html 来查看结果,但您将看不到任何内容,因为场景尚未渲染。


第 4 步: 相机!

要渲染某些内容,首先我们需要将相机添加到场景中,以便渲染器知道应该从哪个角度渲染内容。 Three.js 中有几种类型的相机,但您可能只会使用 THREE.PerspectiveCamera。这种类型的相机呈现出我们所看到的世界的场景。让我们创建一个:

var camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 10000);

“要渲染某些内容,首先我们需要将相机添加到场景中,以便渲染器知道应该从哪个角度渲染内容。”

创建相机比我们迄今为止所做的其他事情要复杂一些。第一个参数定义 FOV(视野),即从相机所在位置可以看到的角度。 45 度的 FOV 看起来很自然。接下来,我们定义相机的比率。这始终是渲染器的宽度除以高度,除非您想实现一些特殊效果。最后两个数字定义了对象与要绘制的相机的距离。

现在我们必须稍微向后和向上移动相机,因为在 Three.js 中创建的所有对象都将其位置设置在场景中间(x: 0, y: 0, z: 0)默认:

我的小书坊源码(三层实现)
我的小书坊源码(三层实现)

可以实现用户的在线注册、登陆后可以添加图书、购买图书,可以对图书类别、出版社、价格等进行饼图分析默认帐号/密码:51aspx/51aspx该系统采用三层接口开发,App_Code下为三层结构的代码文件,适合三层入门者学习使用数据绑定控件使用的是GridView,顶部公用文件采用了UserControl用户控件调用DB_51aspx下为Sql数据库文件,附件即可【该源码由51aspx提供】

下载
camera.position.y = 160;
camera.position.z = 400;

z 坐标在观看者的方向上为正,因此具有较高 z 位置的对象会显得离您更近(在这种情况下,由于我们移动了相机,所有对象都会显得更远)来自您)。

现在,让我们将相机添加到场景并渲染它:

scene.add(camera);

renderer.render(scene, camera);

添加相机就像添加立方体一样。下一行使用该相机渲染场景。现在您可以打开浏览器,您应该看到以下内容:

基础入门:使用Three.js进行WebGL开发

您应该只能看到立方体的顶部。这是因为我们将相机向上移动,但它仍然看起来在它的正前方。这个问题可以通过让相机知道它应该看什么位置来解决。在设置相机位置的行之后添加此行:

camera.lookAt(cube.position);

传入的唯一参数是相机将看到的位置。现在,场景看起来更好了,但立方体仍然是黑色,无论您在创建立方体时设置了什么颜色:

基础入门:使用Three.js进行WebGL开发


第 5 步: 灯!

立方体是黑色的,因为场景中没有灯光,所以它就像一个完全黑的房间。您会看到白色背景,因为除了立方体之外没有任何东西可以绘制。为了避免这种情况,我们将使用一种称为天空盒的技术。基本上,我们将添加一个大立方体来显示场景的背景(如果是开放空间,通常是一些远处的地形)。那么,让我们创建这个盒子。此代码应位于 renderer.render 调用之前:

var skyboxGeometry = new THREE.CubeGeometry(10000, 10000, 10000);
var skyboxMaterial = new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.BackSide });
var skybox = new THREE.Mesh(skyboxGeometry, skyboxMaterial);

scene.add(skybox);

此代码与创建多维数据集的代码类似。但这一次的几​​何形状要大得多。我们还使用了 THREE.MeshBasicMaterial 因为我们不需要照亮天空盒。另外,请注意传递给材料的附加参数:side: THREE.BackSide。由于立方体将从内部显示,因此我们必须更改绘制的侧面(通常,Three.js 只绘制外墙)。

现在渲染的场景是全黑的。为了解决这个问题,我们必须向场景添加灯光。我们将使用 THREE.PointLight,它像灯泡一样发出光。在天空盒后添加这些行:

var pointLight = new THREE.PointLight(0xffffff);
pointLight.position.set(0, 300, 200);

scene.add(pointLight);

如您所见,我们创建了白色的点光源,然后将其位置设置为向上和向后一点,以照亮立方体的正面和顶部。最后,灯光像任何其他对象一样添加到场景中。打开浏览器,您应该会看到一个彩色阴影立方体:

基础入门:使用Three.js进行WebGL开发

但是立方体仍然很无聊。让我们为其添加一些动作。


第 6 步: 行动!

现在我们将为场景添加一些运动。让我们让立方体绕 Y 轴旋转。但首先,我们必须改变渲染场景的方式。一次 renderer.render 调用,渲染场景的当前状态一次。因此,即使我们以某种方式为立方体设置动画,我们也不会看到它移动。要改变这一点,我们必须将渲染循环添加到我们的应用程序中。这可以使用专门为此目的创建的 renderAnimationFrame 函数来实现。大多数主要浏览器都支持它,对于那些不支持它的浏览器,Three.js 附带了自己的 polyfill。那么,让我们改变一下:

renderer.render(scene, camera);

对此:

function render() {
	renderer.render(scene, camera);
	
	requestAnimationFrame(render);
}

render();

实际上,那里没有循环,因为它会冻结浏览器。 requestAnimationFrame 函数的行为有点像 setTimeout,但它会在浏览器准备就绪时调用该函数。因此,显示的场景没有任何变化,立方体仍然没有移动。让我们解决这个问题。 Three.js自带了THREE.Clock,可以用来实现对象的平滑动画。首先在render函数定义之前进行初始化:

var clock = new THREE.Clock;

现在,每次调用 clock.getDelta 时,它都会返回自上次调用以来的时间(以毫秒为单位)。这可以用来旋转立方体,如下所示:

cube.rotation.y -= clock.getDelta();

render 函数中的 renderer.renderrequestAnimationFrame 调用之间添加此行。它只是减去立方体在 Y 轴上旋转所花费的时间(记住它以弧度为单位)来顺时针旋转立方体。现在打开浏览器,您应该看到立方体顺时针平稳旋转。


结论

在本系列的这一部分中,您学习了如何准备场景、添加对象和灯光以及如何为事物设置动画。您可以尝试该应用程序,添加更多或不同的对象、灯光。由你决定。下次我将向您展示如何使用纹理以及如何使用粒子创建一些漂亮的效果。如果遇到任何问题,请不要忘记查看文档。

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

553

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

374

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

731

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

477

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

394

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

990

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

656

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

551

2023.09.20

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

36

2026.01.14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 8.6万人学习

Rust 教程
Rust 教程

共28课时 | 4.4万人学习

Vue 教程
Vue 教程

共42课时 | 6.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号