带你入门three.js——从0到1实现一个3d可视化地图(一)

简介: 前言终于到周末了,前几篇的文章一直给大家介绍2d,canvas 和svg的一些东西。7月份我打算输出3篇万字长文带大家系统地学习可视化表达的3种方式,svg、canvas、webgl。所以这是第一篇文章3d的。读完本篇文章,你可以学到什么对于three.js 这个框架有一个简单的理解,可以入门下。学习three中的Raycaster,主要是用鼠标来判断当前选择的是哪一个物体。我用一个简单的实例 带大家用three实现简单的可视化地球案例 。3d框架的选择——three.js1.为什么选择three.js官网对 「Threejs」 的介绍非常简单:“Javascript 3D l

前言



终于到周末了,前几篇的文章一直给大家介绍2d,canvas 和svg的一些东西。7月份我打算输出3篇万字长文带大家系统地学习可视化表达的3种方式,svg、canvas、webgl。所以这是第一篇文章3d的。读完本篇文章,你可以学到什么


  1. 对于three.js 这个框架有一个简单的理解,可以入门下。


  1. 学习three中的Raycaster,主要是用鼠标来判断当前选择的是哪一个物体。


  1. 我用一个简单的实例 带大家用three实现简单的可视化地球案例 。


3d框架的选择——three.js


1.为什么选择three.js


官网对 「Threejs」 的介绍非常简单:“Javascript 3D library”。「openGL」 是一个跨平台3D/2D的绘图标准,「WebGL」 则是「openGL」 在浏览器上的一个实现。web前端开发人员可以直接用「WebGL」 接口进行编程,但 「WebGL」 只是非常基础的绘图API,需要编程人员有很多的数学知识、绘图知识才能完成3D编程任务,而且代码量巨大。「Threejs」「WebGL」 进行了封装,让前端开发人员在不需要掌握很多数学知识和绘图知识的情况下,也能够轻松进行web 3D开发,降低了门槛,同时大大提升了效率。总结来一句话:就是你不懂计算机图形学,只要理解了three.js的一些基本概念你可以。


Threejs 的基本要素——场景



定义如下:


「场景」:是一个三维空间,所有物品的容器,可以把场景想象成一个空房间,接下来我们会往房间里放要呈现的物体、相机、光源等。


用代码表示就是如下:


const scene = new THREE.Scene();


你就把他想象成一个房间,然后你可以往里面去添加一些物体,加一个正方体哈,加矩形,什么都可以。其实three.js 整个之间的关系是一个 「树形结构」


Threejs 的基本要素——相机📷



「相机」:Threejs必须要往场景中添加一个相机,相机用来确定位置、方向、角度,相机看到的内容就是我们在屏幕上看到的内容。在程序运行过程中,可以调整相机的位置、方向和角度。


three.js 中的相机分为两种一种是正交相机📷 和透视相机📷,接下来我给大家一一介绍,但是理解照相机的情况下,你要先理解一个概念——视椎体


透视相机


视锥体是摄像机可见的空间,看上去像截掉顶部的金字塔。视锥体由6个裁剪面围成,构成视锥体的4个侧面称为上左下右面,分别对应屏幕的四个边界。为了防止物体离摄像机过近,设置近切面,同时为了防止物体离摄像机太远而不可见,设置远切面。


image.png

oc 就是照相机的位置, 近平面、和远平面图中已经标注。从图中可以看出,棱台组成的6个面之内的东西,是可以被看到的。影响透视照相机的大小因素:


  1. 摄像机视锥体垂直视野角度 也就是图中的「a」


  1. 摄像机视锥体近端面  也就是图中的 「near plane」


  1. 摄像机视锥体远端面  也就是图中的「far plane」


  1. 摄像机视锥体长宽比   「表示输出图像的宽和高之比」


对应的three 中的照相机:


const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );


透视相机最大的特点:就是符合我们人眼观察事物的特点, 近大远小。



近大远小的背后的实现原理就是相机会有一个投影矩阵:  投影矩阵的做的事情很简单,就是把视锥体转换成一个正方体。所以远截面的点就要缩小, 近距离的反而放大。

image.png

image.gif投影矩阵.png


正交相机


正交相机的特点就是视锥体的是一个立方体


在这种投影模式下,无论物体距离相机距离远或者近,在最终渲染的图片中物体的大小都保持不变。


这对于渲染2D场景或者UI元素是非常有用的。如图:


image.png


正交相机.png


three中代码如下:


const camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 );

说完相机就要介绍下图形的组成形式了。


Threejs 的基本要素——网格



在计算机的世界里,一条弧线是由有限个点构成的有限条线段连接得到的。当线段数量越多,长度就越短,当达到你无法察觉这是线段时,一条平滑的弧线就出现了。计算机的三维模型也是类似的。只不过线段变成了平面,普遍用三角形组成的网格来描述。我们把这种模型称之为 Mesh 模型。


一条弧线由多条线段得到,线段的数量越多,越接近弧线。不懂的小伙伴,可以看下我的这篇文章:面试官问我会canvas? 我可以绘制一个烟花🎇动画里面「贝塞尔曲线可以是用一段段小线段去拟合起来的」


three.js 背后所有的图形在进行渲染之前, 都会进行三角化, 然后交给webgl 去渲染。

Threejs提供了一些常见的几何形状,有三维的也有二维的,三维的比如长方体、球体等,二维的比如长方形圆形等,如果默认提供的形状不能满足需求,也可以自定义通过定义顶点和顶点之间的连线绘制自定义几何形状,更复杂的模型还可以用建模软件建模后导入。


2d


image.png


image-20210703111412606.png


3d


image.png


image-20210703111444001.png


有了形状,可能渲染出来的图形没有美丽的样子,这时候材质就出来了。组成的mesh其实是有两个部分:


材质(Material)+几何体(Geometry)就是一个 mesh,Threejs提供了集中比较有代表性的材质,常用的用漫反射、镜面反射两种材质,还可以引入外部图片,贴到物体表面,成为纹理贴图。大家有兴趣可以自己去试一下。如图:


image.png


image-20210703111750461.png


Threejs 的基本要素——灯光



假如没有光,摄像机看不到任何东西,因此需要往场景添加光源,为了跟真实世界更加接近,Threejs支持模拟不同光源,展现不同光照效果,有点光源、平行光、聚光灯、环境光等。


AmbientLight(环境光)



环境光会均匀的照亮场景中的所有物体,环境光不能用来投射阴影,因为它没有方向。


const light = new THREE.AmbientLight( 0x404040 ); // soft white light


平行光(DirectionalLight)



平行光是沿着特定方向发射的光。这种光的表现像是无限远,从它发出的光线都是平行的。常常用平行光来模拟太阳光 的效果; 太阳足够远,因此我们可以认为太阳的位置是无限远,所以我们认为从太阳发出的光线也都是平行的。


const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );


点光源(PointLight)


从一个点向各个方向发射的光源。一个常见的例子是模拟一个灯泡发出的光。


const light = new THREE.PointLight( 0xff0000, 1, 100 );


聚光灯(SpotLight)



光线从一个点沿一个方向射出,随着光线照射的变远,光线圆锥体的尺寸也逐渐增大。


const spotLight = new THREE.SpotLight( 0xffffff );


还有一些其他的灯光,感兴趣的小伙伴可以自行去three.js 官网查看。


Threejs 的基本要素——渲染器


渲染器就是去渲染你场景中灯光、相机、网格哇。


let renderer = new THREE.WebGLRenderer({
    antialias: true, // true/false表示是否开启反锯齿
    alpha: true, // true/false 表示是否可以设置背景色透明
    precision: 'highp', // highp/mediump/lowp 表示着色精度选择
    premultipliedAlpha: false, // true/false 表示是否可以设置像素深度(用来度量图像的分率)
    preserveDrawingBuffer: true, // true/false 表示是否保存绘图缓冲
    maxLights: 3, // 最大灯光数
    stencil: false // false/true 表示是否使用模板字体或图案


three.js大体的一些要素我都介绍过了,接下面就进入在正题了,three.js 如何实现一个可视化地图呢?

相关文章
|
2月前
|
前端开发 机器人 API
前端大模型入门(一):用 js+langchain 构建基于 LLM 的应用
本文介绍了大语言模型(LLM)的HTTP API流式调用机制及其在前端的实现方法。通过流式调用,服务器可以逐步发送生成的文本内容,前端则实时处理并展示这些数据块,从而提升用户体验和实时性。文章详细讲解了如何使用`fetch`发起流式请求、处理响应流数据、逐步更新界面、处理中断和错误,以及优化用户交互。流式调用特别适用于聊天机器人、搜索建议等应用场景,能够显著减少用户的等待时间,增强交互性。
339 2
|
2月前
|
编解码 数据可视化 前端开发
如何使用 D3.js 创建一个交互式的地图可视化?
如何使用 D3.js 创建一个交互式的地图可视化?
|
21天前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
21天前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
29 0
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
|
29天前
|
监控 前端开发 JavaScript
React 静态网站生成工具 Next.js 入门指南
【10月更文挑战第20天】Next.js 是一个基于 React 的服务器端渲染框架,由 Vercel 开发。本文从基础概念出发,逐步探讨 Next.js 的常见问题、易错点及解决方法,并通过具体代码示例进行说明,帮助开发者快速构建高性能的 Web 应用。
70 10
|
27天前
|
数据采集 存储 JavaScript
如何使用Puppeteer和Node.js爬取大学招生数据:入门指南
本文介绍了如何使用Puppeteer和Node.js爬取大学招生数据,并通过代理IP提升爬取的稳定性和效率。Puppeteer作为一个强大的Node.js库,能够模拟真实浏览器访问,支持JavaScript渲染,适合复杂的爬取任务。文章详细讲解了安装Puppeteer、配置代理IP、实现爬虫代码的步骤,并提供了代码示例。此外,还给出了注意事项和优化建议,帮助读者高效地抓取和分析招生数据。
如何使用Puppeteer和Node.js爬取大学招生数据:入门指南
|
3月前
|
JavaScript 前端开发 小程序
一小时入门Vue.js前端开发
本文是作者关于Vue.js前端开发的快速入门教程,包括结果展示、参考链接、注意事项以及常见问题的解决方法。文章提供了Vue.js的基础使用介绍,如何安装和使用cnpm,以及如何解决命令行中遇到的一些常见问题。
一小时入门Vue.js前端开发
|
2月前
|
存储 JavaScript 前端开发
前端开发:Vue.js入门与实战
【10月更文挑战第9天】前端开发:Vue.js入门与实战
|
2月前
|
自然语言处理 JavaScript 前端开发
JavaScript高级——ES6基础入门
JavaScript高级——ES6基础入门
26 1
|
2月前
|
机器学习/深度学习 自然语言处理 前端开发
前端大模型入门:Transformer.js 和 Xenova-引领浏览器端的机器学习变革
除了调用API接口使用Transformer技术,你是否想过在浏览器中运行大模型?Xenova团队推出的Transformer.js,基于JavaScript,让开发者能在浏览器中本地加载和执行预训练模型,无需依赖服务器。该库利用WebAssembly和WebGPU技术,大幅提升性能,尤其适合隐私保护、离线应用和低延迟交互场景。无论是NLP任务还是实时文本生成,Transformer.js都提供了强大支持,成为构建浏览器AI应用的核心工具。
495 1