【小沐学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
    • 13.4 WebGL / SpriteJS.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等多种格式和技术。
在这里插入图片描述

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

13.4 WebGL / SpriteJS.js

https://github.com/spritejs/spritejs/
https://spritejs.com/#/
SpriteJS 是跨平台的高性能图形系统,它能够支持web、node、桌面应用和小程序的图形绘制和实现各种动画效果。

SpriteJS Next 是SpriteJS的新版本,在浏览器端支持 webgl2 渲染,并可向后兼容降级为 webgl 和 canvas2d。
在这里插入图片描述

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

结语

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

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

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

相关文章

AI绘画作品的展示和变现

AI绘画作品的展示和推广技巧 如何通过AI绘画打造独特的个人IP 4.1 AI绘画作品买卖 平台一&#xff1a;抖音 抖音平台有「抖音图文扶持计划」&#xff0c;还会不定期推出图文伙伴计划、图文热点来了等&#xff0c;大家起号的时候更容易 当你的每篇作品阅读量稳定在 1W 时&…

pm2启动的node项目访问不了,npm start却可以访问

netstat -ntlp输入该命令&#xff0c;查看启动的服务端口是否有被监听到&#xff0c;如3001&#xff0c;4000之类的&#xff0c;是node项目启动时候自己配的那个&#xff0c; 若没有&#xff0c;则执行 pm2 delete [app-id/app-name] 先删除启动的这个项目 例如pm2 delete my…

【时事篇-05】20240112 150元存46只货币基金

背景需求&#xff1a; 【时事篇-02】20240110 365天存钱法&#xff08;sum法&#xff09;-CSDN博客文章浏览阅读371次&#xff0c;点赞10次&#xff0c;收藏8次。【时事篇-02】20240110 365天存钱法&#xff08;sum法&#xff09;https://blog.csdn.net/reasonsummer/article/…

C++ //练习 6.33 编写一个递归函数,输出vector对象的内容。

C Primer&#xff08;第5版&#xff09; 练习 6.33 练习 6.33 编写一个递归函数&#xff0c;输出vector对象的内容。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /******************************************************…

力扣面试题 16.21. 交换和(哈希表)

Problem: 面试题 16.21. 交换和 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 1.分别求取array1与array2数组每一个元素的和&#xff08;sum1与sum2&#xff09;并同时将array2的元素存入一个set集合中&#xff1b; 2.如果sum1和sum2的和为奇数&#xff0c;则不…

【开源】JAVA+Vue.js实现天然气工程运维系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统角色分类2.2 核心功能2.2.1 流程 12.2.2 流程 22.3 各角色功能2.3.1 系统管理员功能2.3.2 用户服务部功能2.3.3 分公司&#xff08;施工单位&#xff09;功能2.3.3.1 技术员角色功能2.3.3.2 材料员角色功能 2.3.4 安…

Spring Boot 笔记 010 创建接口_更新用户头像

1.1.1 usercontroller中添加updateAvatar&#xff0c;校验是否为url PatchMapping("updateAvatar")public Result updateAvatar(RequestParam URL String avatarUrl) {userService.updateAvatar(avatarUrl);return Result.success();} 1.1.2 userservice //更新头像…

【开源】JAVA+Vue.js实现海南旅游景点推荐系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户端2.2 管理员端 三、系统展示四、核心代码4.1 随机景点推荐4.2 景点评价4.3 协同推荐算法4.4 网站登录4.5 查询景点美食 五、免责说明 一、摘要 1.1 项目介绍 基于VueSpringBootMySQL的海南旅游推荐系统&#xff…

云原生介绍与容器的基本概念

云原生介绍 1、云原生的定义 云原生为用户指定了一条低心智负担的、敏捷的、能够以可扩展、可复制的方式最大化地利用云的能力、发挥云的价值的最佳路径。 2、云原生思想两个理论 第一个理论基础是&#xff1a;不可变基础设施。 第二个理论基础是&#xff1a;云应用编排理…

OK-Robot机器人实现零样本算法 可在非结构化环境下完成拾取与放置任务

纽约大学的机器人专家团队与Meta人工智能学院研发人员共同合作开发了一种新型机器人&#xff0c;该机器人具备在非结构化环境下的认知能力&#xff0c;可在陌生房间利用视觉语言模型&#xff08;VLMs&#xff09;&#xff0c;进行物品的抓取与放置。在论文当中&#xff0c;该团…

使用word2vec+tensorflow自然语言处理NLP

目录 介绍&#xff1a; 搭建上下文或预测目标词来学习词向量 建模1&#xff1a; 建模2&#xff1a; 预测&#xff1a; 介绍&#xff1a; Word2Vec是一种用于将文本转换为向量表示的技术。它是由谷歌团队于2013年提出的一种神经网络模型。Word2Vec可以将单词表示为高维空间…

片上网络NoC(4)——直连拓扑

目录 一、前言 二、直连拓扑 三、总结 一、前言 本文中&#xff0c;我们将继续介绍片上网络中拓扑相关的内容&#xff0c;主要介绍直连拓扑&#xff0c;在此之前&#xff0c;我们已经介绍过了拓扑的指标&#xff0c;这将是继续阅读本文的基础&#xff0c;还没有了解相关内容…