【小沐学GIS】基于WebGL绘制三维数字地球Earth(OpenGL)

🍺三维数字地球系列相关文章如下🍺:
1【小沐学GIS】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)第一期
2【小沐学GIS】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)第二期
3【小沐学GIS】基于C++绘制太阳系SolarSystem(OpenGL、glfw、glut)
4【小沐学GIS】基于OpenSceneGraph(OSG)绘制三维数字地球Earth
5【小沐学GIS】基于C#绘制三维数字地球Earth(OpenGL)
6【小沐学GIS】基于Python绘制三维数字地球Earth(OpenGL)
7【小沐学GIS】基于Android绘制三维数字地球Earth(OpenGL)
8【小沐学GIS】基于WebGL绘制三维数字地球Earth(OpenGL)

文章目录

  • 1、简介
    • 1.1 WebGL简介
    • 1.2 WebGL入门示例
      • 1.2.1 初始场景
      • 1.2.2 绘制点
      • 1.2.3 绘制单色三角形
      • 1.2.4 绘制彩色三角形
  • 2、开源代码
    • 2.1 cambecc/earth(3d全球气象地球)
    • 2.2 mapbox/webgl-wind(2d风场地球)
    • 2.3 github(3dgithub地球)
    • 2.4 cesium.js
  • 13、测试代码
    • 13.1 WebGL
    • 13.2 WebGL / three.js
    • 13.3 WebGL / Babylon.js
  • 结语

1、简介

1.1 WebGL简介

WebGL(全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和 数据视觉化 。
在这里插入图片描述
OpenGL ES则是从OpenGL中移除了许多陈旧无用的特性之后的一个轻量级的OpenGL框架,在保持轻量级的同时,OpenGL ES仍然具有足够的能力来渲染出精美的三维图形。
在这里插入图片描述
相对于传统网页,支持WebGL的浏览器底层接入了OpenGL/OpenGL ES标准,WebGL通过实现标准支持着色器语言编程语言GLSL ES,在我们实际开发过程中,GLSL ES通常是以字符串的形式存在JavaScript中,我们可以通过JavaScript修改GLSL ES字符串来改变着色器程序。

1.2 WebGL入门示例

  • WebGL绘图流程如下
    第 1 步 - 准备画布并获取 WebGL 渲染上下文,我们获取当前的 HTML canvas 对象并获取其 WebGL 渲染上下文。
    第 2 步 - 定义几何并将其存储在缓冲区对象中,我们定义几何的属性,如顶点、索引、颜色等,并将它们存储在 JavaScript 数组中。然后,我们创建一个或多个缓冲区对象并将包含数据的数组传递给相应的缓冲区对象。在示例中,我们将三角形的顶点存储在 JavaScript 数组中,并将该数组传递给顶点缓冲区对象。
    第 3 步 - 创建和编译着色器程序,我们编写顶点着色器和片段着色器程序,编译它们,并通过链接这两个程序来创建组合程序。
    第 4 步 - 将着色器程序与缓冲区对象相关联,我们关联缓冲区对象和组合着色器程序。
    第 5 步 - 绘制所需对象(三角形),此步骤包括清除颜色、清除缓冲区位、启用深度测试、设置视口等操作。最后,您需要使用方法之一绘制所需的图元 - drawArrays()或drawElements()。

在这里插入图片描述

  • WebGL着色器执行过程
    在这里插入图片描述

1.2.1 初始场景

<canvas id="canvas"></canvas>
<script>const canvas=document.getElementById('canvas');canvas.width=window.innerWidth;canvas.height=window.innerHeight;const gl=canvas.getContext('webgl');gl.clearColor(0.5,0.5,0.5,1);gl.clear(gl.COLOR_BUFFER_BIT);
</script>
  • 测试如下:
    在这里插入图片描述

1.2.2 绘制点

<canvas id="canvas"></canvas>
<!-- 顶点着色器 -->
<script id="vertexShader" type="x-shader/x-vertex">void main() {gl_Position = vec4(0.0, 0.0, 0.0, 1.0);gl_PointSize = 100.0;}
</script>
<!-- 片元着色器 -->
<script id="fragmentShader" type="x-shader/x-fragment">void main() {gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);}
</script>
<script>// canvas 画布const canvas = document.getElementById('canvas');canvas.width=window.innerWidth;canvas.height=window.innerHeight;// webgl画笔const gl = canvas.getContext('webgl');// 顶点着色器const vsSource = document.getElementById('vertexShader').innerText;// 片元着色器const fsSource = document.getElementById('fragmentShader').innerText;// 初始化着色器initShaders(gl, vsSource, fsSource);// 指定将要用来清理绘图区的颜色gl.clearColor(0., 0.0, 0.0, 1.0);// 清理绘图区gl.clear(gl.COLOR_BUFFER_BIT);// 绘制顶点gl.drawArrays(gl.POINTS, 0, 1);function initShaders(gl,vsSource,fsSource){//创建程序对象const program = gl.createProgram();//建立着色对象const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);//把顶点着色对象装进程序对象中gl.attachShader(program, vertexShader);//把片元着色对象装进程序对象中gl.attachShader(program, fragmentShader);//连接webgl上下文对象和程序对象gl.linkProgram(program);//启动程序对象gl.useProgram(program);//将程序对象挂到上下文对象上gl.program = program;return true;}function loadShader(gl, type, source) {//根据着色类型,建立着色器对象const shader = gl.createShader(type);//将着色器源文件传入着色器对象中gl.shaderSource(shader, source);//编译着色器对象gl.compileShader(shader);//返回着色器对象return shader;}
</script>
  • 测试如下:
    在这里插入图片描述

1.2.3 绘制单色三角形

<!doctype html>
<html><body><canvas width = "300" height = "300" id = "my_Canvas"></canvas><script>/* Step1: Prepare the canvas and get WebGL context */var canvas = document.getElementById('my_Canvas');var gl = canvas.getContext('experimental-webgl');/* Step2: Define the geometry and store it in buffer objects */var vertices = [-0.5, 0.5, -0.5, -0.5, 0.0, -0.5,];// Create a new buffer objectvar vertex_buffer = gl.createBuffer();// Bind an empty array buffer to itgl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);// Pass the vertices data to the buffergl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);// Unbind the buffergl.bindBuffer(gl.ARRAY_BUFFER, null);/* Step3: Create and compile Shader programs */// Vertex shader source codevar vertCode ='attribute vec2 coordinates;' + 'void main(void) {' + ' gl_Position = vec4(coordinates,0.0, 1.0);' + '}';//Create a vertex shader objectvar vertShader = gl.createShader(gl.VERTEX_SHADER);//Attach vertex shader source codegl.shaderSource(vertShader, vertCode);//Compile the vertex shadergl.compileShader(vertShader);//Fragment shader source codevar fragCode = 'void main(void) {' + 'gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);' + '}';// Create fragment shader objectvar fragShader = gl.createShader(gl.FRAGMENT_SHADER);// Attach fragment shader source codegl.shaderSource(fragShader, fragCode);// Compile the fragment shadergl.compileShader(fragShader);// Create a shader program object to store combined shader programvar shaderProgram = gl.createProgram();// Attach a vertex shadergl.attachShader(shaderProgram, vertShader); // Attach a fragment shadergl.attachShader(shaderProgram, fragShader);// Link both programsgl.linkProgram(shaderProgram);// Use the combined shader program objectgl.useProgram(shaderProgram);/* Step 4: Associate the shader programs to buffer objects *///Bind vertex buffer objectgl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);//Get the attribute locationvar coord = gl.getAttribLocation(shaderProgram, "coordinates");//point an attribute to the currently bound VBOgl.vertexAttribPointer(coord, 2, gl.FLOAT, false, 0, 0);//Enable the attributegl.enableVertexAttribArray(coord);/* Step5: Drawing the required object (triangle) */// Clear the canvasgl.clearColor(0.5, 0.5, 0.5, 0.9);// Enable the depth testgl.enable(gl.DEPTH_TEST); // Clear the color buffer bitgl.clear(gl.COLOR_BUFFER_BIT);// Set the view portgl.viewport(0,0,canvas.width,canvas.height);// Draw the trianglegl.drawArrays(gl.TRIANGLES, 0, 3);</script></body>
</html>
  • 测试如下:
    在这里插入图片描述

1.2.4 绘制彩色三角形

<canvas id="canvas"></canvas>
<!-- 顶点着色器 -->
<script id="vertexShader" type="x-shader/x-vertex">attribute vec4 a_position;attribute vec4 a_color;varying vec4 vColor;void main(){gl_Position = a_position;vColor = a_color;}
</script>
<!-- 片元着色器 -->
<script id="fragmentShader" type="x-shader/x-fragment">precision mediump float;varying vec4 vColor;void main() {gl_FragColor = vColor;}
</script>
<script>// canvas 画布const canvas = document.getElementById('canvas');canvas.width=window.innerWidth;canvas.height=window.innerHeight;// webgl画笔const gl = canvas.getContext('webgl');// 顶点着色器const vsSource = document.getElementById('vertexShader').innerText;// 片元着色器const fsSource = document.getElementById('fragmentShader').innerText;// 初始化着色器initShaders(gl, vsSource, fsSource);// 初始化场景// gl.viewport(0, 0, canvas.clientWidth, canvas.clientHeight);gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);//区别在这里,用上面那行代码三角形无法显示gl.clearColor(0, 0, 0, 1);gl.clear(gl.COLOR_BUFFER_BIT);//获取的是着色器里的position变量var attLocation = gl.getAttribLocation(gl.program,'a_position');//获取顶点着色器中的color变量var attLocationColor = gl.getAttribLocation(gl.program,'a_color');var vertex_data = [0, 0,0, 0.5,0.7, 0]var vertex_color = [1.0, 0.0, 0.0, 1.0,0.0, 1.0, 0.0, 1.0,0.0, 0.0, 1.0, 1.0];var vertex_vbo = create_vbo(vertex_data);gl.bindBuffer(gl.ARRAY_BUFFER, vertex_vbo);gl.enableVertexAttribArray(attLocation);gl.vertexAttribPointer(attLocation, 2, gl.FLOAT,false,0,0);var color_vbo = create_vbo(vertex_color);gl.bindBuffer(gl.ARRAY_BUFFER,color_vbo);gl.enableVertexAttribArray(attLocationColor);gl.vertexAttribPointer(attLocationColor, 4, gl.FLOAT,false,0,0);gl.drawArrays(gl.TRIANGLES, 0, 3)function initShaders(gl,vsSource,fsSource){//创建程序对象const program = gl.createProgram();//建立着色对象const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);//把顶点着色对象装进程序对象中gl.attachShader(program, vertexShader);//把片元着色对象装进程序对象中gl.attachShader(program, fragmentShader);//连接webgl上下文对象和程序对象gl.linkProgram(program);//启动程序对象gl.useProgram(program);//将程序对象挂到上下文对象上gl.program = program;return true;}function loadShader(gl, type, source) {//根据着色类型,建立着色器对象const shader = gl.createShader(type);//将着色器源文件传入着色器对象中gl.shaderSource(shader, source);//编译着色器对象gl.compileShader(shader);//返回着色器对象return shader;}function create_vbo(data){// 生成缓存对象var vbo = gl.createBuffer();// 绑定缓存gl.bindBuffer(gl.ARRAY_BUFFER, vbo);// 向缓存中写入数据;gl.STATIC_DRAW这个常量,定义了这个缓存中内容的更新频率gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);// 将绑定的缓存设为无效;这是为了防止WebGL中的缓存一致保留,而出现和预想不一致的情况gl.bindBuffer(gl.ARRAY_BUFFER, null);// 返回生成的VBOreturn vbo;}
</script>
  • 测试如下:
    在这里插入图片描述

2、开源代码

2.1 cambecc/earth(3d全球气象地球)

https://github.com/cambecc/earth
一个全球天气状况可视化项目。

  • 依赖安装,需提前安装 Node.js 和 npm。
  • 使用git下载项目并安装npm依赖包。
git clone https://github.com/cambecc/earth
cd earth
npm install

在这里插入图片描述
在这里插入图片描述

  • 启动服务器
node dev-server.js 8080

在这里插入图片描述

  • 浏览器服务器访问地址
http://127.0.0.1:8080

在这里插入图片描述

2.2 mapbox/webgl-wind(2d风场地球)

https://github.com/mapbox/webgl-wind
WebGL 驱动的风力发电可视化。 能够以 60fps 的速度渲染多达 100 万个风粒子。

  • 执行如下脚本:
npm install
npm run build
npm start
# open http://127.0.0.1:1337/demo/

在这里插入图片描述

  • 浏览器访问如下:
http://127.0.0.1:1337/demo/

在这里插入图片描述

2.3 github(3dgithub地球)

在这里插入图片描述

2.4 cesium.js

【小沐学GIS】基于Cesium实现三维数字地球Earth(CesiumJS入门安装)

13、测试代码

13.1 WebGL

基于WebGL基础代码实现地球绘制效果。

  • 地球测试代码的运行效果如下:
    在这里插入图片描述

13.2 WebGL / three.js

https://threejs.org/
three.js是在Web端创建3D程序的图形引擎,WebGL是一个只能画点、线、三角形的底层图形系统,直接使用WebGL开发应用往往需要写大量的代码,three.js对其进行了封装大大简化了Web 3D应用的开发。
在这里插入图片描述

  • 地球测试代码的运行效果如下:
    在这里插入图片描述

13.3 WebGL / Babylon.js

https://www.babylonjs.com/
Babylonjs是一个开源的Web3D渲染引擎,支持高性能3D、WebXR、glTF等多种格式和技术。
在这里插入图片描述

  • 地球测试代码的运行效果如下:
    在这里插入图片描述
    在这里插入图片描述

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/679373.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】C的整理记录

前言 该笔记是建立在已经系统学习过C语言的基础上&#xff0c;笔者对C语言的知识和注意事项进行整理记录&#xff0c;便于后期查阅&#xff0c;反复琢磨。C语言是一种面向过程的编程语言。 原想在此阐述一下C语言的作用&#xff0c;然而发觉这些是编程语言所共通的作用&#…

一键打造属于自己漏扫系统

0x01 工具介绍 本系统是对Web中间件和Web框架进行自动化渗透的一个系统,根据扫描选项去自动化收集资产,然后进行POC扫描,POC扫描时会根据指纹选择POC插件去扫描,POC插件扫描用异步方式扫描.前端采用vue技术,后端采用python fastapi。 0x02 安装与使用 1、Docker部署环境 编译…

C语言学习记录

牛牛学说话之-字符_牛客题霸_牛客网 (nowcoder.com) 总结&#xff1a; 字符定义为char,对应%c 整数定义为int&#xff0c;对应%d 分数对应float&#xff0c;对应%f,内存小&#xff0c;速度快 分数对应double,对应%lf&#xff0c;范围广&#xff0c;精度高 保留几位小数就是…

C++入门学习(二十七)跳转语句—break语句

1、与switch语句联合使用 C入门学习&#xff08;二十三&#xff09;选择结构-switch语句-CSDN博客 #include <iostream> #include <string> using namespace std;int main() { int number;cout<<"请为《斗萝大路》打星(1~5※)&#xff1a;" &…

Linux操作系统基础(十一):RPM软件包管理器

文章目录 RPM软件包管理器 一、rpm包的卸载 二、rpm包的安装 RPM软件包管理器 rpm&#xff08;英文全拼&#xff1a;redhat package manager&#xff09; 原本是 Red Hat Linux 发行版专门用来管理 Linux 各项软件包的程序&#xff0c;由于它遵循GPL规则且功能强大方便&…

单片机学习笔记---AT24C02(I2C总线)

目录 有关储存器的介绍 存储器的简介 存储器简化模型 AT24C02介绍 AT24C02引脚及应用电路 I2C总线介绍 I2C电路规范 开漏输出模式和弱上拉模式 其中一个设备的内部结构 I2C通信是怎么实现的 I2C时序结构 起始条件和终止条件 发送一个字节 接收一个字节 发送应答…

Stable Diffusion 模型下载:ToonYou(平涂卡通)

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 ToonYou 是一个平涂风格的卡通模型&#xff0c;它的画风独特、光感强烈、画面…

Ubuntu Desktop - Details (设备详情)

Ubuntu Desktop - Details [设备详情] 1. OverviewReferences 1. Overview System Settings -> Details -> Overview ​ References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

单片机在物联网中的应用

单片机&#xff0c;这个小巧的电子设备&#xff0c;可能听起来有点技术性&#xff0c;但它实际上是物联网世界中的一个超级英雄。简单来说&#xff0c;单片机就像是各种智能设备的大脑&#xff0c;它能让设备“思考”和“行动”。由于其体积小、成本低、功耗低、易于编程等特点…

【C++第二阶段】赋值运算符重载

你好你好&#xff01; 以下内容仅为当前认识&#xff0c;可能有不足之处&#xff0c;欢迎讨论&#xff01; 文章目录 赋值运算符重载 赋值运算符重载 实验①&#xff0c;还没有对析构运算符重载时 #include<iostream> #include<string> using namespace std;clas…

失去中国市场的三星仍是全球第一,但中国手机无法失去海外市场

随着2023年分析机构公布全球手机市场和中国手机市场的数据&#xff0c;业界终于看清中国市场早已没有以前那么重要&#xff0c;三星、苹果这些国际品牌对中国市场的依赖没有他们想象的那么严重&#xff0c;相反中国手机对海外市场比以往任何时候都要更依赖了。 三星在2023年被苹…

消息队列使用的四种场景介绍

一、简介 消息队列中间件是分布式系统中重要的组件&#xff0c;主要解决应用耦合&#xff0c;异步消息&#xff0c;流量削锋等问题。 实现高性能&#xff0c;高可用&#xff0c;可伸缩和最终一致性架构。 使用较多的消息队列有ActiveMQ&#xff0c;RabbitMQ&#xff0c;ZeroMQ…

【开源】SpringBoot框架开发个人健康管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 健康档案模块2.2 体检档案模块2.3 健康咨询模块 三、系统展示四、核心代码4.1 查询健康档案4.2 新增健康档案4.3 查询体检档案4.4 新增体检档案4.5 新增健康咨询 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpri…

docker之centos7容器常用命令和服务安装

一、前言 以前我们如果想在windows环境下使用linux系统&#xff0c;最早的是一台主机上安装双机系统&#xff0c;再后来我们有了VMware&#xff0c;可以通过workstations虚拟化平台安装虚拟机。现在我们还可以通过docker安装linux容器&#xff0c;容器更轻量也更便捷。不过凡事…

SpringCloud-高级篇(二十一)

前面解决了消息的可靠性、消息的延迟问题&#xff0c;下面研究一下消息的堆积的问题&#xff1a; &#xff08;1&#xff09;消息堆积问题 消息产生堆积&#xff0c;上限后&#xff0c;最早的消息成为死信&#xff0c;有消息被丢弃&#xff0c;这对安全性较高的业务中是不行的…

HiveSQL——条件判断语句嵌套windows子句的应用

注&#xff1a;参考文章&#xff1a; SQL条件判断语句嵌套window子句的应用【易错点】--HiveSql面试题25_sql剁成嵌套判断-CSDN博客文章浏览阅读920次&#xff0c;点赞4次&#xff0c;收藏4次。0 需求分析需求&#xff1a;表如下user_idgood_namegoods_typerk1hadoop1011hive1…

JAVA设计模式之迭代器模式详解

迭代器模式 1 迭代器模式介绍 迭代器模式是我们学习一个设计时很少用到的、但编码实现时却经常使用到的行为型设计模式。在绝大多数编程语言中&#xff0c;迭代器已经成为一个基础的类库&#xff0c;直接用来遍历集合对象。在平时开发中&#xff0c;我们更多的是直接使用它&a…

解决 postman测试接口报404 Not Found

JDK版本&#xff1a;jdk17 IDEA版本&#xff1a;IntelliJ IDEA 2022.1.3 文章目录 问题描述原因分析解决方案 问题描述 当我使用postman测试接口时&#xff0c;报了 404 Not Found 的错误&#xff0c;报错截图如下所示 但我的后端程序中已经定义了该接口&#xff0c;如下所示 …

C语言指针2.0

1. 指针语法解剖 任意的指针&#xff0c;不管有多复杂&#xff0c;其定义都由两部分组成。 第1部分&#xff1a;指针所指向的数据类型&#xff0c;可以是任意的类型第2部分&#xff1a;指针的名字 char (*p1); // 第2部分&#xff1a;*p1; 第1部分&#xff1a;ch…

分享76个时间日期JS特效,总有一款适合您

分享76个时间日期JS特效&#xff0c;总有一款适合您 76个时间日期JS特效下载链接&#xff1a;https://pan.baidu.com/s/1s7tPGT_ItK7dNK5_qbZkug?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;…