WebGL之绘制三维地球
通过Three.js也许可以很方便的展示出3D模型,但是你知道它是怎么一步一步从构建网格到贴图到最终渲染出3D模型的吗?现在我们直接使用底层的webgl加上一点点的数学知识就可以实现它。
本节实现的效果: WebGL三维地球
内容大纲
构建网格
编写着色器
实现3D地球
构建网格
首先我们要建立球体的三维模型,三维网格模型包括如下属性(不熟悉请复习webgl教程):
- 顶点(position)
- 法线(normal)
- 贴图坐标(uv)
- 顶点索引(indices)
最后要构建出如下所示的经纬球模型
首先可以从xy平面构建圆形,接着再从xz平面将圆形转化为圆球,这其中只需使用到三角函数而已,是不是非常简单。
- 法线使用的是顶点坐标,因为法线与顶点其实方向是一致的
- 顶点索引为6个点,是因为每个面由两个三角形构成
- 贴图uv坐标不需要深度信息,它对应上贴图的xy坐标即可
下面就是构建网格模型的基本逻辑:
const radius = 8;//半径
const n = 20;//经纬度格数
const position = [];//顶点
const normal = [];//法线
const texcoord = [];//uv坐标
const indices = [];//顶点索引
let x, y, z;
for (let i = 0; i < n; i++) {
const rad = Math.PI / n * i - Math.PI / 2;//从-90度开始计算
const r = radius * Math.cos(rad);
y = radius * Math.sin(rad);
for (let j = 0; j < n; j++) {
x = r * Math.sin(xRadian * j);
z = r * Math.cos(xRadian * j);
position.push(x, y, z);
texcoord.push(j / n, i / n);
normal.push(x, y, z); //顶点作为法线,法线从圆心360度放射
const c = i * (n + 1) + j
indices.push(c, c + 1, c + l + 1, c, c + l + 1, c + l);//平面的索引
}
}
编写着色器
和普通着色器相比,只是增加了uv坐标,uv直接通过顶点着色器差值透传到片段着色器即可,在片段着色器使用texture2D函数获取uv坐标对应的颜色,整体上也是比较基础。
// 顶点着色器
attribute vec4 aPosition;
attribute vec4 aNormal;
attribute vec2 aTexcoord;
uniform mat4 modelMatrix;
uniform mat4 vpMatrix;
varying vec3 fragPos;
varying vec3 fragNor;
varying vec2 texcoord;
void main() {
gl_Position = vpMatrix * modelMatrix * aPosition;
fragPos= vec3(modelMatrix * aPosition);
fragNor = vec3(modelMatrix * aNormal);
texcoord = aTexcoord;
}
// 片段着色器
precision mediump float;
uniform vec3 viewPos;
uniform vec3 lightPos;
uniform vec3 lightColor;
uniform vec3 ambientColor;
uniform sampler2D diffMap;
varying vec3 fragPos;
varying vec3 fragNor;
varying vec2 texcoord;
void main() {
vec3 normal = normalize(fragNor);
vec3 color = texture2D(diffMap, texcoord).rgb;
// 光线方向
vec3 lightDir = normalize(lightPos - fragPos);
// 光线方向和法向量夹角
float cosTheta = max(dot(lightDir, normal), 0.0);
// 漫反射
vec3 diffuse = lightColor * color * cosTheta;
// 环境光
// ...
// 高光
// ...
gl_FragColor = vec4(ambient + diffuse + specular, 1.0);
}
实现3D地球
最后实现部分就和之前的webgl基本逻辑一致,不过要准备好地球贴图
图片加载完将构建好的贴图sampler传入着色器即可,其他都是基础业务逻辑,不再详述,这样我们就将三维地球实现了
//...
const vpMatrix = m4.identity();
const uniforms = {
modelMatrix: m4.identity(),
lightPos: [20, 0, -20],
lightColor: [1, 1, 1],
ambientColor: [0.5, 0.5, 0.5],
};
gl.clearColor(0.1, 0.1, 0.1, 1);
gl.enable(gl.DEPTH_TEST);//深度测试
gl.enable(gl.CULL_FACE);//背面剔除
gl.viewport(0, 0, canvas.width, canvas.height); //设置绘图区域
gl.useProgram(program.program);
function animate() {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
m4.multiply(projection, m4.inverse(m4.lookAt(eye, [0, 0, 0], [0, 1, 0])), vpMatrix);
setBuffersAndAttributes(gl, vao);
setUniforms(program, { vpMatrix });
drawBufferInfo(gl, vao);
gl.bindVertexArray(null);
requestAnimationFrame(animate);
};
//加载贴图后执行
createTexture(gl, { src: '/img/earth.jpg', flipY: true }, texture => {
uniforms.diffMap = texture;
setUniforms(program, uniforms );
animate();
});
WebGL之绘制三维地球的更多相关文章
- 无插件,跨平台,基于WebGL的三维地球来了!!!
用户通过浏览器即可递交数据到同一个地理信息系统中,操作简单,跨平台 ,无插件,可扩展,高效共享 ,完美匹配超大数据量发布! 近年来,随着计算机图形学.虚拟现实.卫星遥感.航空摄影.激光雷达等技术的迅猛 ...
- 开源三维地球GIS引擎Cesium常用功能的开发
Cesium是一个非常优秀的三维地球GIS引擎(开源且免费).能够加载各种符合标准的地图图层,瓦片图.矢量图等都支持.支持3DMax等建模软件生成的obj文件,支持通用的GIS计算:支持DEM高程图. ...
- [js] webgl 初探 - 绘制三角形
摘要: 1. webgl 概念挺多的, 顶点着色器.片段着色器, 坐标 2. 绘制前期准备工作好多 目前看的比较好的教材: https://developer.mozilla.org/zh-CN/do ...
- matlab绘制三维图形
原文地址:种三维曲面图. 程序如下: [x,y]=meshgrid(-8:0.5:8); z=sin(sqrt(x.^2+y.^2))./sqrt(x.^2+y.^2+eps); subplot(2, ...
- Python学习(一) —— matplotlib绘制三维轨迹图
在研究SLAM时常常需要对其输出的位姿进行复现以检测算法效果,在ubuntu系统中使用Python可以很好的完成相关的工作. 一. Ubuntu下Python的使用 在Ubuntu下使用Python有 ...
- Matlab绘图基础——绘制三维表面
%绘制三维表面 ------------------------------------- %1.绘制线框图:mesh:每一条曲线称为mesh line %首先利用meshgrid函数产生平面区域内的 ...
- Matlab绘图基础——绘制三维曲线
%% 绘制三维曲线 %plot3函数,其中每一组x,y,z组成一组曲线的坐标参数,选项的定义和plot函数相同. %1.当x,y,z是同维向量时,则x,y,z 对应元素构成一条三维曲线. x0 = 0 ...
- Matlab绘制三维曲面(以二维高斯函数为例)
原文地址为:Matlab绘制三维曲面(以二维高斯函数为例) 寒假学习了一下Python下的NumPy和pymatlab,感觉不是很容易上手.来学校之后,决定继续看完数字图像处理一书.还是想按照上学期的 ...
- Python使用matplotlib绘制三维曲线
本文主要演示如何使用matplotlib绘制三维图形 代码如下: # -*- coding: UTF-8 -*- import matplotlib as mpl from mpl_toolkits. ...
随机推荐
- 获取点击元素的id
1.onclick="dianji(this.id)" 传入id到方法里function dianji(id){ //这个就是id}2. $(document).click(fun ...
- Apache支持Vue router使用 HTML5History 模式
一.前言 前端Vue router 使用history模式,URL会比hash模式好看,这种模式要玩好,还需要后端配置支持,否则会报404错误. 注:1.前端代码省略. 2.此处后台使用Apache服 ...
- CCF(URL映射:80分):字符串处理+模拟
URL映射 CCF201803-3 #include<iostream> #include<cstdio> #include<cstring> #include&l ...
- PTA甲级—数学
1.简单数学 1008 Elevator (20分) 模拟题 #include <cstdio> #include <cstring> #include <string& ...
- 微服务分布式事务之LCN、TCC
在亿级流量架构之分布式事务解决方案对比中, 已经简单阐明了从本机事务到分布式事务的演变过程, 文章的最后简单说明了TCC事务, 这儿将会深入了解TCC事务是原理, 以及理论支持, 最后会用Demo举例 ...
- NIO三大组件之Selector选择器
什么是选择器 选择器的作用是完成IO的多路复用.一个通道代表一条连接通路,通过选择器可以同时监控多个通道的IO(输入输出)状况.选择器和通道的关系,是监控和被监控的关系. 使用 重要的成员 Selec ...
- 开源项目renren-fast开发环境部署(后端部分)
开源项目renren-fast开发环境部署(后端部分) 说明:renren-fast是一个开源的基于springboot的前后端分离手脚架,当前版本是3.0 开发文档需要付费,官方的开发环境部署介绍相 ...
- 如何强制删除一个apk
有些apk安装完后无法卸载,现在收集了一些方法,以及个人的一些手段. 1. 假设该app名为ketech,安装包名为ketech.apk. 2. 查看/data/app里面是否有名称包含ketech的 ...
- Windows包管理器——Scoop 包管理器
Scoop 包管理器 目录 Scoop 包管理器 参考 官方 博客 声明 目录 scoop 安装&&卸载 安装( 使用 powershell) 卸载(软件的使用权归自己所有,一言不合即 ...
- ABP 适用性改造 - 精简 ABP CLI 生成的项目结构
Overview 不管是公司或者个人都会有不同的开发习惯,通过建立项目模板,既可以使开发人员聚焦于业务功能的开发,也可以在一定程度上统一不同开发人员之间的开发风格.在使用 ABP 框架的过程中,对于 ...