WEBGL (全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等。

创建一个场景

本节的目的是简要介绍three.js。我们将首先使用旋转立方体设置场景。页面底部提供了一个工作示例,以防您遇到困难并需要帮助。

在我们开始之前

在使用three.js之前,您需要在某处显示它。将以下HTML保存到计算机上的文件中,以及js /目录中的three.js副本,并在浏览器中打开它。

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>My first three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="js/three.js"></script>
<script>
// Our Javascript will go here.
</script>
</body>
</html>

就这样。下面的所有代码都进入空<script>标记。

创建场景

为了能够显示任何带有three.js的东西,我们需要三件事:场景,相机和渲染器,这样我们就可以用相机渲染场景。

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

我们花一点时间来解释这里发生了什么。我们现在已经设置了场景,我们的相机和渲染器。

在three.js中有几个不同的相机。现在,让我们使用PerspectiveCamera。

第一个属性是视野。FOV是在任何给定时刻在显示器上看到的场景的范围。该值以度为单位。

第二个是宽高比。您几乎总是希望使用元素的宽度除以高度,或者您将得到与在宽屏电视上播放旧电影时相同的结果 - 图像看起来很紧。

接下来的两个属性是近剪裁平面和远剪裁平面。这意味着,远离相机的物体远远超过近或远的物体将不会被渲染。您现在不必担心这一点,但您可能希望在应用中使用其他值以获得更好的性能。

接下来是渲染器。这就是魔术发生的地方。除了我们在这里使用的WebGLRenderer之外,three.js还有其他几个,通常用作旧浏览器用户的后备或者由于某些原因没有WebGL支持的用户。

除了创建渲染器实例之外,我们还需要设置我们希望它渲染应用程序的大小。使用我们想要用我们的应用填充的区域的宽度和高度是个好主意 - 在这种情况下,浏览器窗口的宽度和高度。对于性能密集型应用程序,您还可以为setSize提供较小的值,例如window.innerWidth / 2和window.innerHeight / 2,这将使应用程序渲染为一半大小。

如果您希望保持应用程序的大小但是以较低的分辨率呈现它,可以通过调用setSize并将其作为updateStyle(第三个参数)来调用。例如,假设您的<canvas>具有100%的宽度和高度,setSize(window.innerWidth / 2,window.innerHeight / 2,false)将以半分辨率呈现您的应用。

最后但并非最不重要的是,我们将渲染器元素添加到HTML文档中。这是渲染器用于向我们显示场景的<canvas>元素。

“这一切都很好,但你承诺的那个立方体在哪里?” 我们现在加上吧。

var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );

camera.position.z = 5;

要创建一个立方体,我们需要一个BoxGeometry。这是一个包含多维数据集的所有点(顶点)和填充(面)的对象。我们将来会更多地探讨这个问题。

除了几何外,我们还需要一种材料来为它着色。Three.js有几种材料,但我们暂时坚持使用MeshBasicMaterial。所有材料都采用将应用于它们的属性对象。为了使事情变得非常简单,我们只提供0x00ff00的颜色属性,它是绿色的。这与CSS或Photoshop(十六种颜色)中的颜色相同。

我们需要的第三件事是网格。网格是一个采用几何体的对象,并将一个材质应用于它,然后我们可以将其插入到场景中,并自由移动。

默认情况下,当我们调用scene.add()时,我们添加的东西将被添加到坐标(0,0,0)中。这会导致相机和立方体彼此在一起。为了避免这种情况,我们只需将相机移出一点。

渲染场景

如果您将上面的代码复制到我们之前创建的HTML文件中,您将无法看到任何内容。这是因为我们实际上还没有渲染任何东西。为此,我们需要所谓的渲染或动画循环。

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

这将创建一个循环,使渲染器在每次刷新屏幕时绘制场景(在典型的屏幕上,这意味着每秒60次)。如果您不熟悉在浏览器中编写游戏,您可能会说“我们为什么不创建一个setInterval?” 问题是 - 我们可以,但requestAnimationFrame有许多优点。也许最重要的一点是当用户导航到另一个浏览器标签时它会暂停,因此不会浪费他们宝贵的处理能力和电池寿命。

动画多维数据集

如果您将上面的所有代码插入到我们开始之前创建的文件中,您应该会看到一个绿色框。让旋转它让它变得更有趣。

在animate函数中的renderer.render调用上方添加以下内容:

cube.rotation.x += 0.01;
cube.rotation.y += 0.01;

这将在每一帧(通常每秒60次)运行,并为立方体提供一个很好的旋转动画。基本上,在应用程序运行时您想要移动或更改的任何内容都必须通过动画循环。你当然可以从那里调用其他函数,这样你就不会得到数百行的动画函数。

结果

恭喜!您现在已经完成了第一个three.js应用程序。这很简单,你必须从某个地方开始。

完整代码如下。玩弄它以更好地了解它的工作原理。

<html>
<head>
<title>My first three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="js/three.js"></script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );

var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );

camera.position.z = 5;

var animate = function () {
requestAnimationFrame( animate );

cube.rotation.x += 0.01;
cube.rotation.y += 0.01;

renderer.render( scene, camera );
};

animate();
</script>
</body>
</html>

初识WEBGL的更多相关文章

  1. WebGL入门教程(一)-初识webgl

    一.WebGL和传统网页的区别: 普通网页组成成分:HTML.JavaScript: WebGL网页组成成分:HTML5.JavaScript和GLSL ES(着色器语言 OpenGL ES): 二. ...

  2. WEBGL学习【一】初识WEBGL

    <html lang="zh-CN"> <head> <title>NeHe's WebGL</title> <meta ch ...

  3. WebGL入门教程(五)-webgl纹理

    前面文章: WebGL入门教程(一)-初识webgl WebGL入门教程(二)-webgl绘制三角形 WebGL入门教程(三)-webgl动画 WebGL入门教程(四)-webgl颜色 这里就需要用到 ...

  4. WebGL入门教程(四)-webgl颜色

    前面文章: WebGL入门教程(一)-初识webgl WebGL入门教程(二)-webgl绘制三角形 WebGL入门教程(三)-webgl动画 颜色效果图: 操作步骤: 1.创建HTML5 canva ...

  5. WebGL入门教程(三)-webgl动画

    前面文章: WebGL入门教程(一)-初识webgl WebGL入门教程(二)-webgl绘制三角形 WebGL动画有移动.旋转和缩放,我们将移动.旋转和缩放图形,然后将其绘制到屏幕上,称为变换(tr ...

  6. WebGL入门教程(二)-webgl绘制三角形

    前面已经介绍过了webgl,WebGL入门教程(一)-初识webgl(http://www.cnblogs.com/bsman/p/6128447.html),也知道了如何绘制一个点,接下来就用web ...

  7. WebGL之通过外部传入a_PontSize值改变点着色器vshader内置变量gl_PointSize的值

    最近分配到一个看起来非常简单的优化需求.通过地图上设置工具来改变地图上显示的点的大小和透明度.无非过程就是从控件面板获取到用户设置的值保存到数据库中.然后地图上画点的时候取出设置的值渲染出点即可.前端 ...

  8. 一篇文章理清WebGL绘制流程

    转自:https://www.jianshu.com/p/e3d8a244f3d9 目录 初始化WebGL环境 顶点着色器(Vertex Shader)与片元着色器(Fragment Shader) ...

  9. 初识webgl--我的webgl学习第一课(基于threeJs)

    一,我为什么要学习webgl 一个偶然的机会,在和朋友的聊天过程中,听说了webgl,也许过去也看到过,但是没有特别在意过.原来,JavaScript也可以很好的渲染并在网页上显示三维动画,不用借助插 ...

随机推荐

  1. MYSQL数据库学习----插入、更新、删除

    一:插入数据 1 为表的所有字段插入数据 INSERT INTO 表名 (值1,值2, 值3...); 2 为表的指定字段插入数据 INSERT INTO 表名(字段1,字段2,...) VALUES ...

  2. spark api之一:Spark官方文档 - 中文翻译

    转载请注明出处:http://www.cnblogs.com/BYRans/ 1 概述(Overview) 2 引入Spark(Linking with Spark) 3 初始化Spark(Initi ...

  3. SpringBoot第九篇:整合Spring Data JPA

    作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/10910059.html 版权声明:本文为博主原创文章,转载请附上博文链接! 前言   前面几章, ...

  4. 洛谷 - P2280 - 激光炸弹

    https://www.luogu.org/problemnew/show/P2280 二维前缀和差分的模板题.注意学习二维前缀和的求法,不用又down又right的. #include<bit ...

  5. touch的基本用法

    touch的基本功能是改变文件的时间戳,以下是三种常用用法: 1.创建一个空文件 以当前时间为时间戳创建一个空文件.$ touch touch.txt //touch.txt不存在 2.更改文件时间戳 ...

  6. 数位dp真·浅谈 By cellur925

    预警:由于是从$Vergil$学长那里和$Mathison$大神那里学来的,所以清一色记忆化搜索!qwq 巨佬的数位dp讲解(未来的咕咕日报头条): https://www.luogu.org/blo ...

  7. spring简介、容器、IOC

    对IOC的理解: 在平时的java应用开发中,我们要实现某一个功能或者说是完成某个业务逻辑时至少需要两个或以上的对象来协作完成,在没有使用Spring的时候,每个对象在需要使用他的合作对象时,自己均要 ...

  8. Oracle中dblink的创建与删除

    查询数据库中有哪些dblink连接 select * from dba_objects where object_type='DATABASE LINK'; 删除公有的EMIS_PRODUCTOIN连 ...

  9. 洛谷1736(二维dp+预处理)

    洛谷1387的进阶版,但很像. 1387要求是“全为1的正方形”,取dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1]))吧?这个有“只有对 ...

  10. [APIO2012]派遣 洛谷P1552 bzoj2809 codevs1763

    http://www.codevs.cn/problem/1763/ https://www.lydsy.com/JudgeOnline/problem.php?id=2809 https://www ...