Three.js 入门教程
我在 中使用了 Three.js 我的一些 实验 ,它确实很好地消除了在浏览器中使用 3D 的麻烦。 有了它,您可以创建相机、对象、灯光、材质等,并且您可以选择渲染器,这意味着您可以决定是否要使用 HTML 5 的画布、WebGL 或 SVG 绘制场景。 由于它是开源的,您甚至可以参与该项目。 但现在我将专注于我通过使用它作为引擎所学到的知识,并向您介绍一些基础知识。
尽管 Three.js 非常棒,但有时您可能会遇到困难。 通常,您将需要花费大量时间来研究示例、逆向工程和(在我的情况下当然)寻找特定功能并偶尔 通过 GitHub 提问 。 如果您必须提出问题,顺便说一句,我发现 doob 先生 和 AlteredQualia 非常有帮助!
1. 基础知识
我假设您至少对 3D 有一定的了解,并且对 JavaScript 有一定的熟练程度。 如果您不这样做,那么在尝试使用这些东西之前可能值得学习一下,因为它可能会让人有些困惑。
在我们的 3D 世界中,我们将拥有以下一些内容,我将引导您完成创建过程:
- 一个场景
- 渲染器
- 相机
- 一两个物体(带材料)
当然,您可以做一些疯狂的事情,我希望您能继续这样做并开始在您的浏览器中尝试 3D。
2.支持
只是关于浏览器支持的快速说明。 根据我的经验,就支持哪些渲染器以及底层 JavaScript 引擎的速度而言,Google 的 Chrome 浏览器是最适合使用的浏览器。 Chrome 支持 Canvas、WebGL 和 SVG,而且速度快得惊人。 Firefox 紧随其后,推出了第 4 版。它的 JavaScript 引擎似乎确实比 Chrome 的慢一点,但它对渲染技术的支持同样出色。 Opera 和 Safari 正在添加 WebGL 支持,但它们当前的版本仅支持画布。 Internet Explorer(版本 9+)仅支持画布渲染,而且我还没有听说微软计划添加 WebGL 功能。
3.设置场景
我假设您选择了支持所有渲染技术的浏览器,并且您希望使用画布或 WebGL 进行渲染,因为它们是更标准的选择。 Canvas 比 WebGL 得到更广泛的支持,但值得注意的是,WebGL 在显卡的 GPU 上运行,这意味着您的 CPU 可以专注于其他非渲染任务,例如您尝试执行的任何物理或用户交互。
无论您选择哪种渲染器,您都应该记住,JavaScript 需要针对性能进行优化。 3D 不是浏览器的轻量级任务(而且它甚至是可能的,这真是太棒了),所以要小心了解代码中的瓶颈在哪里,如果可以的话,将它们移除!
话虽如此,假设 您已经下载 了 three.js 并将其包含在您的 HTML 文件中,您将如何设置场景? 像这样:
// set the scene size var WIDTH = 400, HEIGHT = 300; // set some camera attributes var VIEW_ANGLE = 45, ASPECT = WIDTH / HEIGHT, NEAR = 0.1, FAR = 10000; // get the DOM element to attach to // - assume we've got jQuery to hand var $container = $('#container'); // create a WebGL renderer, camera // and a scene var renderer = new THREE.WebGLRenderer(); var camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR ); var scene = new THREE.Scene(); // the camera starts at 0,0,0 so pull it back camera.position.z = 300; // start the renderer renderer.setSize(WIDTH, HEIGHT); // attach the render-supplied DOM element $container.append(renderer.domElement);
不太棘手,真的!
4.制作网格
所以我们有一个场景、一个相机和一个渲染器(我在我的示例代码中选择了一个 WebGL 渲染器)但是我们没有什么可以实际绘制的。 Three.js 实际上支持加载几种不同的标准文件类型,如果您从 Blender、Maya、Cinema4D 或其他任何工具输出模型,这将非常有用。 为简单起见(毕竟这是关于入门!)我将讨论原语。 图元是几何网格,相对基本的网格,如球体、平面、立方体和圆柱体。 Three.js 可让您轻松创建这些类型的原语:
// set up the sphere vars var radius = 50, segments = 16, rings = 16; // create a new mesh with sphere geometry - // we will cover the sphereMaterial next! var sphere = new THREE.Mesh( new THREE.SphereGeometry(radius, segments, rings), sphereMaterial); // add the sphere to the scene scene.add(sphere);
一切都很好,但是球体的材料呢? 在代码中我们使用了一个变量 sphereMaterial 但我们还没有定义它。 首先,我们需要更详细地谈谈材料。
5.材料
毫无疑问,这是 Three.js 最有用的部分之一。 它为您提供了一些常用(而且非常方便)的材质来应用于您的网格:
- "Basic" - which just means that it renders "unlit"
- Lambert
- Phong
还有更多,但再次为了简单起见,我会让您自己发现这些。 特别是在 WebGL 的情况下,这些材料可以成为救命稻草。 为什么? 好吧,因为在 WebGL 中,您必须为渲染的所有内容编写着色器。 着色器本身就是一个很大的话题,但简而言之,它们是用 GLSL(OpenGL 着色器语言)编写的,它告诉 GPU 某些东西应该是什么样子。 这意味着您需要模仿照明、反射等的数学运算。 它会很快变得非常复杂。 感谢 Three.js,如果你不想这样做,你不必这样做,因为它为你抽象了。 但是,如果您想编写着色器,您也可以使用 MeshShaderMaterial 来实现,因此这是一个灵活的设置。
然而,现在让我们将朗伯材质应用于球体:
// create the sphere's material var sphereMaterial = new THREE.MeshLambertMaterial( { // a gorgeous red. color: 0xCC0000 });
还值得指出的是,除了颜色之外,在创建材质时还可以指定其他属性,例如平滑或环境贴图。 您应该 查看 Wiki 页面 ,了解您可以在材质上设置的各种属性,事实上,引擎为您提供的任何对象。 threejs.org 最近也如 雨后春笋般涌现,它提供了更具吸引力的 API 视图。
6. 灯!
如果您现在要渲染场景,您会看到一个红色圆圈。 尽管我们应用了 Lambert 材质,但场景中没有光,因此默认情况下 Three.js 将恢复为完整的环境光,这与平面着色相同。 让我们用一个简单的光源来解决这个问题:
// create a point light var pointLight = new THREE.PointLight( 0xFFFFFF ); // set its position pointLight.position.x = 10; pointLight.position.y = 50; pointLight.position.z = 130; // add to the scene scene.add(pointLight);
7.渲染
值得注意的是,我们现在实际上已经设置好要渲染的所有内容。 但我们实际上需要继续这样做:
// draw! renderer.render(scene, camera);
这就是它的样子:
不过,您可能想要渲染不止一次,所以如果您要进行循环,您应该真正使用 requestAnimationFrame; 这是迄今为止在浏览器中处理动画的最聪明的方式。 目前还没有完全支持它,所以我完全建议您看一下 Paul Irish 的 shim 。
8. 公共对象属性
如果您花时间查看 Three.js 的代码,您会看到很多对象“继承”自 Object3D。 这是一个包含一些非常有用的属性的基础对象,例如 位置 、 旋转 和 缩放 信息。 特别是我们的 Sphere 是一个继承自 Object3D 的 Mesh,它向其中添加了自己的属性: geometry 和 materials 。 我为什么要提到这些? 好吧,您不太可能希望在屏幕上只显示一个什么都不做的球体,这些属性值得研究,因为它们允许您即时操纵网格和材质的底层细节。
// sphere geometry sphere.geometry // which contains the vertices and faces sphere.geometry.vertices // an array sphere.geometry.faces // also an array // its position sphere.position // has x, y and z properties sphere.rotation // same sphere.scale // ... same
9.小秘密
我只是想快速指出 Three.js 的一个快速陷阱,例如,如果您修改网格的顶点,您会注意到在渲染循环中没有任何变化。 为什么? 好吧,因为 Three.js(据我所知)缓存网格数据作为一种优化。 您实际需要做的是向 Three.js 标记某些内容已更改,以便它可以重新计算所需的任何内容。 您可以通过以下方式执行此操作:
// changes to the vertices sphere.geometry.__dirtyVertices = true; // changes to the normals sphere.geometry.__dirtyNormals = true;
还有更多,但我发现的那两个是最有用的。 您显然应该只标记已更改的内容以避免不必要的计算。
结论
好吧,我希望您发现 Three.js 的简短介绍对您有所帮助。 没有什么比亲自动手尝试更棒的了,我怎么推荐都不为过。 在浏览器中本机运行 3D 非常有趣,使用像 Three.js 这样的引擎可以为您消除很多麻烦,让您可以制作一些非常酷的东西。
为了帮助您解决问题,我 在这篇实验文章中总结了源代码 ,因此您可以将其用作参考。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: Three 着色器简介
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论