利用javascript和WebGL绘制地球 【翻译】

原翻译:利用javascript和WebGL绘制地球 【翻译】

在我们所有已知的HTML5API中,WebGL可能是最有意思的一个,利用这个API我们能够在浏览器中创造出炫酷3D场景的能力。本文将完整的向你展示一些炫酷是如何实现的。

需要特别指出的是,这篇教程我们将会构建一个地球行星模型,这个模型可以像一个兴奋的人一样环绕的旋转,另外,它可能使我们可以获得一些其他程序员的称赞,好吧,就这么多了。

准备

这篇教程我们将会用到一个令人着迷的WebGL插件:three.js. 这个插件跟JQuery有点像,不过它是针对WebGL的,它将很多复杂的原生API访问接口进行了抽象,从而让我们可以更轻易的利用WebGL的特性。

在HTML中,我们的可以通过正常的script标签引入这个插件,如下:

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

此处我们引用的是CDN版本,如果你有必要,可以使用本地的方法引入。然后我们需要确保WebGL有东西可以在上面进行渲染。这里我们有个灵活的做法:我们可以直接将一般的Div或者Canvas写到HTML中,或者我们可以另外用JS创建并且追加canvas元素到Dom里后再去渲染。这里我们采用第一种容易点的方法,如下:

<body><div id="container"></div> <script src="earth.js"></script> </body>

添加完script标签连接到Dom中后,我们的HTML部分差不多就完成了。

下一步

Tree.js本身是趋向把东西做的非常接近真实的3D桌面程序的。我们拥有一个场景,有一些东西现场直播,然后通过摄像机去浏览,然后有些灯光,特效,渲染在整场景上面,当然他们自身也全都是3D对象。这个场景的元素列表似乎有点吓人,在我们的earth.js文件里,所有的这些元素都可以当成形状变量,Javascript文件如下:

var scene,camera,light, renderer, earthObject; var WIDTH = window.innerWidth - 30, HEIGHT = window.innerHeight - 30; var angle = 45, aspect = WIDTH / HEIGHT, near = 0.1, far = 3000; 

有些额外的变量也定义在这里了,WIDTH,HEIGHT 变量用来获取我们画布的宽与高,下面的其他变量之后将会用来设置我们相机的位置。对于几乎所有的3D对象来说,所有这些元素都是共通的,无论是平台还是环境,所以在这里我们习惯性的将这些家伙写到一起。然而利用Three.js我们可以轻松的实现,我们将看看所有这些元素是如何在同一时刻融合到项目中的。

环境

首先,我们需要启用新变量并初始化他们,从而使我们的地球模型可以展示的更炫。我们可以先设置每个处理环境因素的变量:

var container = document.getElementById('container'); camera = new THREE.PerspectiveCamera(angle, aspect, near, far); camera.position.set(0, 0, 0); scene = new THREE.Scene(); light = new THREE.SpotLight(0xFFFFFF, 1, 0, Math.PI / 2, 1); light.position.set(4000, 4000, 1500); light.target.position.set (1000, 3800, 1000);

下面是针对上面代码执行情况的描述:

  • 在我们的HTMl中抓取container对象
  • 我们用之前声明的变量设置camera对象(更多关于cameras是如何在3D中工作的信息,可以点击这里)
  • 通过position.set方法设置camera的位置, 这个方法需要携带一个维度(x, y, z)参数对象, 可能你已经想到了, 我们将会使用这个camera去定位我们的3D对象,本教程中的3D对象就是我们的地球模型。
  • 接下来设置我们的light对象。如果没有light对象做渲染的话,那么整个模型出来的效果将会是一片漆黑,所以我们必须细心的注意这一步骤。Three.js的SpotLight object对象拥有与我们的camera对象大致相同的参数,只不过这个对象的第一个参数colour必须为十六进制的值,然后剩余的其他参数与camera基本相同。
  • 最后,我们需要设置我们的画布对象renderer.另外一个需要确保的点则是:我们需要提前将画布对象完整的渲染到了屏幕上,再次强调,如果没有完成这一步,那么整个画布将会什么也看不见,一片漆黑。我们给画布添加了去锯齿效果,并且将这个效果作为Dom元素添加到我们的原始容器中。

现在我们需要通过将整个地球粘贴在网上一样的方式来构建自身整个模型。代码如下:

var earthGeo = new THREE.SphereGeometry (30, 40, 400), earthMat = new THREE.MeshPhongMaterial(); var earthMesh = new THREE.Mesh(earthGeo, earthMat); earthMesh.position.set(-100, 0, 0); earthMesh.rotation.y=5; scene.add(earthMesh);

在这里我们创建了一个网状(Mesh)对象,这个网状是一种可以被用来装扮并看起来像地球形状的对象,然后给这个对象添加一些几何结构,外观包装,或者一些有质感的材料来包裹这个网状体。我们同样会将这个对象设置适当的在位置,与其他参数对象一样,我们会并且将Mesh对象添加到我们的场景(scene)中。

如下有个样例。这里面有些额外的渲染效果,稍后我们将会讲解。这个样例看起来离我们想要的越来越近了。

蓝色星球

接下来有趣的部分是给这个家伙制作皮肤。首先我们将会使用一张漫反射贴图,它会让这个家伙看起来更像个地图。你可以像下面的方式一样添加:

// diffuse map
earthMat.map = THREE.ImageUtils.loadTexture('images/earthmap1k.jpg');

如果你想要质感更好些的话,你可以尝试用这个图片,或者你可以去google搜索一张你想要的图片都行。高分辨率的图都可以。

现在这个模型看起来没那么糟糕了,但是我们仍然可以通过引用一点地形描绘的方式,使整个模型看起来更真实些。这个地球有一些高山,为了确保区分太阳系的其他星球,我们需要使用凹凸地图(bump map), 在3D模型中, 凹凸地图是黑白图,使用鲜明的白色去凸显图像凹凸不平的部分(例如我们示例中的:山脉)。

// bump map
earthMat.bumpMap = THREE.ImageUtils.loadTexture('images/elev_bump_16ka.jpg'); earthMat.bumpScale = 8;

使用上面的图片我们差不多达到了效果,再次强调,使用过Google搜索“Earth bump map”会获得大量的选择,但是如果你感觉都不好的话,你可以点击这个连接。 运行了以上的代码,我们将会看到如下效果:

让它转起来!

接下来剩余的事情就是我们给这个地球模型添加一些动画效果,为此,我们需要两个新的方法,我们命名为render()animate()

function animate() { requestAnimationFrame(animate); render(); }

我们的animate()方法并不是很复杂,通过自身递归连续的调用requestAnimationFrame()方法,anmiate()会请求我们的render()方法,让我们看看render()方法的代码:

function render() { var clock = new THREE.Clock(), delta = clock.getDelta(); earthMesh.rotation.y += rotationSpeed * delta; renderer.render(scene, camera); }

我们看看上面的代码做了些什么工作。每次render()方法被请求,它便会让地球模型在y轴上缓缓的转动起来(此处你可以选择设置任意的转动次数,我们在这里利用getDelta()方法构建一个时钟对象来控制转动次数,当然你可以不使用这种方法)。然后render()方法会执行清理画布操作,这是防止画布乱掉很重要的步骤,最后它会渲染我们的场景(以及场景对象中的其他所有对象)和我们的camera对象。

最后

当然,拥有拖拽操作会让我们的地球模型的体验更好,OrbitControls.js是一个可以为我们地球模型提供鼠标驱动旋转效果能力的脚本,并且它为我们的平流层里添加一些星星或者云作为地球模型的背景同样也并不困难,如果你并不嫌麻烦的话,你甚至可以利用WebGL的着色器(shaders)为你的星球添加一个平流层。

运行代码,你可以看到一个样例,在CodePen中最终的Demo如下:

通过按住鼠标拖动和滚动鼠标滑轮来查看效果(或者点击此处demo

结尾

WebGL和Three.js变得越发的具有挑战性,因为他们偶尔会要求我们要像3D艺术家一样,利用场景,画布,camera去完成我们的工作,最终的结果就是做出了一些加令人印象深刻的东西。如果你专注于在这个技术上的话,你可以通过在浏览器中使用3D特性创造出一些有趣的可能性。如果坚持它,相信不久你就很可能获取一些非凡的成绩。

原文地址:Building the Earth with WebGL and JavaScript

转载于:https://www.cnblogs.com/zivxiaowei/p/4356571.html

利用javascript和WebGL绘制地球 【翻译】相关推荐

  1. vtk 利用体渲染绘制地球

    vtk 利用体渲染绘制地球 之前看到有人问体渲染绘制地球的颜色渲染不对.难道还有构建体素数据来渲染地球这种玩法吗?果断试一下: 1 找地球图片数据 2 贴图实现地球的可视化(TexturedSpher ...

  2. PHP3d地球,three.js绘制地球、飞机与轨迹的效果示例

    对于three.js不太熟悉的朋友们可以参考这篇文章,threejs官网:https://threejs.org/ 首先我们来看下要实现的效果 这个缩小后的图片,下面我们来看下近距离的动态效果.. 效 ...

  3. webgl 实现地球月球绕转(时间原因有内存泄漏问题后续优化)带阴影雾化光照效果

    代码纯webgl原生实现 <!DOCTYPE html> <html><head><meta charset="UTF-8">< ...

  4. 这是如何更好地利用JavaScript数组的方法

    by pacdiv 由pacdiv 这是如何更好地利用JavaScript数组的方法 (Here's how you can make better use of JavaScript arrays) ...

  5. 利用javascript实现简体与繁体的转换

    这段代码只是利用Javascript实现了简繁体的相互转化,因为仅操作当前页面,无刷新所以速度快,转换过程流畅. 话不多说上正餐: var Default_isFT = 0 //默认是否繁体,0-简体 ...

  6. WebGL 绘制Line的bug(一)

    插播一则广告(长期有效) MONO哥需要在武汉招JavaScript工程师若干 要求:对前端技术(JavasScript.HTML.CSS),对可视化技术(Canvas.WebGL)有浓厚的兴趣 基础 ...

  7. 用webgl绘制一个彩色旋转立方体

    #用webgl绘制一个旋转立方体 ** 学习交流欢迎加群:789723098,博主会将一些demo整理共享 ** 今天给大家分享一个用webgl写的简单的三维场景:转动的交互式彩色立方体,其六个面的颜 ...

  8. canvas绘制地球围绕太阳转、月球围绕地球转

    素材(放到img中,与html同级): 太阳 地球 月亮 <!DOCTYPE html> <html><head><meta charset="ut ...

  9. 【图形基础篇】04 # GPU与渲染管线:如何用WebGL绘制最简单的几何图形?

    说明 [跟月影学可视化]学习笔记. 图形系统是如何绘图的? 一个通用计算机图形系统主要包括 6 个部分,分别是: 输入设备 中央处理单元:首先,数据经过 CPU 处理,成为具有特定结构的几何信息. 图 ...

最新文章

  1. 云知声联合亿咖通科技成立合资公司,布局汽车 AI 芯片
  2. 用一个创业故事串起操作系统原理(一)
  3. Cell子刊:人类微生物组参考基因集中的单体基因
  4. Delphi匿名方法(三):扩展本地变量的生命周期
  5. 将list对象转换为QuerySet对象
  6. HTTP笔记-SOAP基本概念
  7. 哪个专业学python语言_想学Python编程?你真的适合吗?
  8. 嵌入式Linux入门4:版本控制git的使用
  9. Python稳基修炼之计算机等级考试易错细节题3(含答案)
  10. 通用DbContext封装
  11. [PyTorch] 安装
  12. 使用Bind配置DNS Load Balancing
  13. AutoAnswer使用指南(QQ、微信自动接听)
  14. html-css-js的几款前端开发工具
  15. Vray渲染器和Corona渲染哪个更好用?
  16. Photoshop下载
  17. vscode配置和快捷键
  18. 前端实现炫酷动效_7款纯CSS3实现的炫酷动画应用
  19. 【操作系统】王道考研 笔记总结目录(完结)
  20. 线性代数学习笔记——第三十九讲——直线与平面的位置关系

热门文章

  1. AI快速入门学习的经验积累-最佳学习路线图谱梳理
  2. php无表单上传文件,php – 如何使用没有实体类的表单上传文件
  3. linux下的科学软件下载,十分科学app-十分科学官网版下载v1.4.3-Linux公社
  4. python线性表顺序存储实现_数据结构——基于C的线性表的顺序存储结构的基本操作的实现...
  5. decode函数python在哪里_Python基础知识——encode和decode函数
  6. c html canvas,HTML5 canvas
  7. 不是说一个源程序中只能有一个public类?怎么内部类可以用public?
  8. 栈----生产者消费者实例
  9. 031_MessageBox弹框
  10. elasticsearch 客户端工具_万字长文:详解 Spring Boot 中操作 ElasticSearch