Cesium渲染模块之概述
1. 引言
Cesium是一款三维地球和地图可视化开源JavaScript库,使用WebGL来进行硬件加速图形,使用时不需要任何插件支持,基于Apache2.0许可的开源程序,可以免费用于商业和非商业用途
Cesium官网:Cesium: The Platform for 3D Geospatial
Cesium GitHub站点:CesiumGS/cesium: An open-source JavaScript library for world-class 3D globes and maps (github.com)
API文档:Index - Cesium Documentation
通过阅读源码,理清代码逻辑,有助于扩展与开发,笔者主要参考了以下两个系列的文章
渲染是前端可视化的核心,本文描述Cesium的渲染模块概述
2. WebGL渲染流程
WebGL(或者说OpenGL)的绘制流程(图形渲染管线,Graphics Pipeline)如下:
- 顶点着色(vertex shader)阶段将CPU传入的数据进行一定的变换处理
- 图元装配(shape assembly)阶段的就是上阶段的顶点数据处理成图元(如,三角形)
- 几何着色(geometry shader)阶段是根据一定规则将输入的图元变更或输出更多的图元(可选)
- 光栅化(rasterization)阶段的是将上阶段的图元进行计算得到图元占据的屏幕像素列表
- 片元着色(fragment)阶段是将上阶段生成的片元进行着色处理后
- 测试与混合阶段计算片元的深度、颜色等从而进行舍弃或保留
绘制流程繁琐,然而,我们能配置的只有三个蓝色的着色器部分。几何着色器可选,一般配置顶点着色器和片段着色器即可,即,以下步骤就是配置顶点着色器和片段着色器
2.1 生成顶点数据
生成顶点缓冲对象(Vertex Buffer Objects, VBO)并加载数据:
const vertices = new Float32Array([
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
0.0, 0.5, 0.0,
]);
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
2.2 链接属性数据
顶点数组对象(Vertex Array Object, VAO)与VBO绑定,用于保存属性数据(先绑定VAO,再创建VBO就会绑定到VAO上):
const vao = gl.createVertexArray();
gl.bindVertexArray(vao);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(0)
2.3 创建顶点着色器
创建顶点着色器(Vertex Shader)并编译:
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, `
attribute vec3 aPos;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
`);
gl.compileShader(vertexShader);
2.4 创建片段着色器
创建片段着色器(Fragment Shader)并编译:
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, `
#version 100
void main()
{
gl_FragColor = vec4(1.0, 0.5, 0.2, 1.0);
}
`);
gl.compileShader(fragmentShader);
2.5 链接着色器
着色器程序对象(Shader Program Object)是多个着色器合并之后并最终链接完成的版本:
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
2.6 绘制
开始绘制:
gl.clearColor(0.2, 0.3, 0.3, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(shaderProgram);
gl.drawArrays(gl.TRIANGLES, 0, 3);
2.7 流程总结
上述几乎可以说是最简化的WebGL渲染流程,包含的基本要素有
- VBO,顶点缓冲对象 --------> 存顶点数据
- VAO,顶点数组对象(WebGL 2支持)--------> 存顶点属性
- Shader,着色器(包括顶点和片段着色器) --------> 运算和渲染
- Shader Program,着色器程序 --------> 连接着色器
此外,常用的还有:
- Texture,纹理(通常是一张图片)
- Framebuffer,帧缓冲对象(FBO)
- Renderbuffer,渲染缓冲对象(RBO)
- CubeMap,立方体贴图
3. Cesium渲染模块
查看Cesium渲染模块中的文件:
$ ls packages/engine/Source/Renderer/
AutomaticUniforms.js
Buffer.js
BufferUsage.js
ClearCommand.js
ComputeCommand.js
ComputeEngine.js
Context.js
ContextLimits.js
CubeMap.js
CubeMapFace.js
DrawCommand.js
Framebuffer.js
FramebufferManager.js
MipmapHint.js
MultisampleFramebuffer.js
Pass.js
PassState.js
PixelDatatype.js
RenderState.js
Renderbuffer.js
RenderbufferFormat.js
Sampler.js
ShaderBuilder.js
ShaderCache.js
ShaderDestination.js
ShaderFunction.js
ShaderProgram.js
ShaderSource.js
ShaderStruct.js
Texture.js
TextureCache.js
TextureMagnificationFilter.js
TextureMinificationFilter.js
TextureWrap.js
UniformState.js
VertexArray.js
VertexArrayFacade.js
createUniform.js
createUniformArray.js
demodernizeShader.js
freezeRenderState.js
loadCubeMap.js
通过文件名,不难发现,Cesium的渲染模块主要包含:
- Buffer
- VAO
- Shader
- Texture
- Framebuffer
- Renderbuffer
- CubeMap
以上是WebGL渲染流程常见的对象,另外Cesium渲染模块还有:
- Command,指令对象(包含ClearCommand、ComputeCommand、DrawCommand)
- Pass,通道(渲染顺序)
- Sampler,采样器
- Uniform,GPU全局变量
- Context,WebGL上下文
3.1 Context对象
相关代码文件:
- Context.js
- ContextLimits.js
Context对象是对WebGL上下文对象的封装,包含Pass、Uniform等,并且对WebGL 1.0和WebGL 2.0做了兼容处理:
function Context(canvas, options) {
this._canvas = canvas;
this._originalGLContext = glContext;
this._gl = glContext;
this._webgl2 = webgl2;
this._id = createGuid();
this._clearColor = new Color(0.0, 0.0, 0.0, 0.0);
this._clearDepth = 1.0;
this._clearStencil = 0;
// ...
const us = new UniformState();
const ps = new PassState(this);
const rs = RenderState.fromCache();
this._defaultPassState = ps;
this._defaultRenderState = rs;
// ...
RenderState.apply(gl, rs, ps);
}
3.2 Buffer对象
相关代码文件:
- Buffer.js
- BufferUsage.js
Buffer对象主要包含顶点缓冲对象(Vertex Buffer Objects, VBO)和索引缓冲对象(Index Buffer Object,IBO)
function Buffer(options) {
const gl = options.context._gl;
gl.bindBuffer(bufferTarget, buffer);
gl.bufferData(bufferTarget, hasArray ? typedArray : sizeInBytes, usage);
gl.bindBuffer(bufferTarget, null);
}
Buffer.createVertexBuffer = function (options) {
return new Buffer({
// ...
});
};
Buffer.createIndexBuffer = function (options) {
const buffer = new Buffer({
// ...
});
return buffer;
};
3.3 VAO对象
相关代码文件:
- VertexArray.js
- VertexArrayFacade.js
顶点数组对象(Vertex Array Object, VAO)与VBO绑定,用于保存属性数据
function VertexArray(options) {
// ...
const context = options.context;
const gl = context._gl;
const attributes = options.attributes;
const indexBuffer = options.indexBuffer;
let vao;
vao = context.glCreateVertexArray();
context.glBindVertexArray(vao);
bind(gl, vaAttributes, indexBuffer);
context.glBindVertexArray(null);
}
3.4 Shader对象
相关代码文件:
- ShaderBuilder.js
- ShaderCache.js
- ShaderStruct.js
- ShaderSource.js
- ShaderProgram.js
- ShaderFunction.js
- ShaderDestination.js
Cesium渲染模块中的Shader对象包含从创建GLSL到创建Shader Program整个流程
流程大致为:
- Cesium中支持分段编写GLSL代码,包括ShaderStruct、ShaderFunction、ShaderDestination
- 将分段的代码组合成GLSL,即ShaderSource
- 使用ShaderSource创建的ShaderProgram会缓存起来,即ShaderCache
- 需要新的ShaderProgram时,先查询缓存中是否有,有就复用,无则创建
3.5 Texture对象
主要代码文件:
- Texture.js
- TextureCache.js
- TextureMagnificationFilter.js
- TextureMinificationFilter.js
- TextureWrap.js
Cesium中的Texture对象是对WebGL中Texture对象的进一步封装:
function Texture(options) {
// ...
const context = options.context;
const gl = context._gl;
const textureTarget = gl.TEXTURE_2D;
const texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(textureTarget, texture);
// Source: ImageData, HTMLImageElement, HTMLCanvasElement, or HTMLVideoElement
gl.texImage2D(
textureTarget,
0,
internalFormat,
pixelFormat,
PixelDatatype.toWebGLConstant(pixelDatatype, context),
source
);
gl.bindTexture(textureTarget, null);
this.sampler = defined(options.sampler) ? options.sampler : new Sampler();
}
3.6 Framebuffer对象
主要代码文件:
- Framebuffer.js
- FramebufferManager.js
- MultisampleFramebuffer.js
Cesium中的Framebuffer对象是对WebGL中Framebuffer对象的进一步封装:
function Framebuffer(options) {
// ...
this._gl = gl;
this._framebuffer = gl.createFramebuffer();
this._bind();
this._colorTextures[i] = texture;
this._colorRenderbuffers[i] = renderbuffer;
this._depthTexture = texture;
this._depthRenderbuffer = renderbuffer;
this._stencilRenderbuffer = renderbuffer;
this._depthStencilTexture = texture;
this._depthStencilRenderbuffer = renderbuffer;
this._unBind();
}
3.7 Renderbuffer对象
主要代码文件:
- Renderbuffer.js
- RenderState.js
- RenderbufferFormat.js
Cesium中的Renderbuffer对象是对WebGL中Renderbuffer对象的进一步封装:
function Renderbuffer(options) {
// ...
const gl = context._gl;
this._renderbuffer = this._gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderbuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, format, width, height);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
}
3.8 CubeMap对象
主要代码文件:
- CubeMap.js
- CubeMapFace.js
- loadCubeMap.js
Cesium中的CubeMap对象是对WebGL中CubeMap对象的进一步封装:
function CubeMap(options) {
// ...
const gl = context._gl;
const textureTarget = gl.TEXTURE_CUBE_MAP;
const texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(textureTarget, texture);
gl.texImage2D()
// ...
gl.bindTexture(textureTarget, null);
this.sampler = defined(options.sampler) ? options.sampler : new Sampler();
}
3.9 Command
主要代码文件:
- ClearCommand.js
- DrawCommand.js
- ComputeEngine.js
- ComputeCommand.js
Command对象主要有三类:
- ClearCommand
- DrawCommand
- ComputeCommand
Command对象包含执行的指令参数和执行方法,比如最简单的ClearCommand:
function ClearCommand(options) {
// ...
this.color = options.color;
this.depth = options.depth;
this.stencil = options.stencil;
this.renderState = options.renderState;
this.framebuffer = options.framebuffer;
this.owner = options.owner;
this.pass = options.pass;
}
ClearCommand.prototype.execute = function (context, passState) {
context.clear(this, passState);
};
ClearCommand包含颜色、深度、通道等指令参数和执行方法 context.clear(this, passState)
3.10 Pass
主要代码文件:
- Pass.js
- PassState.js
Pass是一种渲染优先级,数值越低,等级越高:
const Pass = {
ENVIRONMENT: 0,
COMPUTE: 1,
GLOBE: 2,
TERRAIN_CLASSIFICATION: 3,
CESIUM_3D_TILE: 4,
CESIUM_3D_TILE_CLASSIFICATION: 5,
CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW: 6,
OPAQUE: 7,
TRANSLUCENT: 8,
VOXELS: 9,
OVERLAY: 10,
NUMBER_OF_PASSES: 11,
};
3.11 Sampler
主要代码文件:
- Sampler.js
Sampler是将采样方式封装:
function Sampler(options) {
// ...
this._wrapS = wrapS;
this._wrapT = wrapT;
this._minificationFilter = minificationFilter;
this._magnificationFilter = magnificationFilter;
this._maximumAnisotropy = maximumAnisotropy;
}
3.12 Uniform
主要代码文件:
- createUniform.js
- UniformState.js
- createUniformArray.js
Uniform是对WebGL中一系列Uniform的封装,比如UniformFloat:
function UniformFloat(gl, activeUniform, uniformName, location) {
// ...
this.name = uniformName;
this.value = undefined;
this._value = 0.0;
this._gl = gl;
this._location = location;
}
UniformFloat.prototype.set = function () {
if (this.value !== this._value) {
this._value = this.value;
this._gl.uniform1f(this._location, this.value);
}
};
4. 参考资料
[1]WebGL2RenderingContext - Web APIs | MDN (mozilla.org)
[2]LearnOpenGL CN (learnopengl-cn.github.io)
[3]Cesium教程系列汇总 - fu*k - 博客园 (cnblogs.com)
[4]Renderbuffer Object - OpenGL Wiki (khronos.org)
[5]基于JavaScript的OpenGL 01 之Hello Triangle - 当时明月在曾照彩云归 - 博客园 (cnblogs.com)
Cesium渲染模块之概述的更多相关文章
- Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基础文件配置,Web框架的本质,服务器程序和应用程序(wsgiref服务端模块,jinja2模板渲染模块)的使用
Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基 ...
- (原)Unreal渲染模块 管线 - 着色器(1)
@author: 白袍小道 转载悄悄说明下 随缘查看,施主开心就好 说明: 本篇继续Unreal搬山部分的渲染模块的Shader部分, 主要牵扯模块RenderCore, ShaderCore, RH ...
- (原)Unreal渲染模块 管线 - 程序和场景查询
@author: 白袍小道 查看随意,转载随缘 第一部分: 这里主要关心加速算法,和该阶段相关的UE模块的结构和组件的处理. What-HOW-Why-HOW-What(嘿嘿,老规矩) 1.渲 ...
- (原)Unreal渲染模块 源码和实例分析说明
@author:白袍小道 说明 1.由于小道就三境武夫而已,而UE渲染部分不仅管理挺大,而且牵扯技术和内容驳杂,所以才有这篇梳理. 2.尽量会按书籍和资料,源码,小模块的调试和搬山(就是敲键盘)..等 ...
- (原)Unreal 渲染模块 渲染流程
@author:白袍小道 浏览分享随缘,评论不喷亦可. 扯淡部分: 在temp中,乱七八糟的说了下大致的UE过程.下面我们还是稍微别那么任性,一步步来吧. UE渲染模块牵扯到场景遍历. ...
- (原)Unreal 渲染模块引言Temp
@author:白袍小道 引言 本文只在对Unreal渲染模块做一些详细的理解,务求能分析出个大概. 其中框架的思想和实现的过程,是非常值得学习和推敲一二的. 涉及资源系统,材 ...
- DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render
DRF框架 全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...
- drf框架 - 请求模块 | 渲染模块
Postman接口工具 官方 https://www.getpostman.com/ get请求,携带参数采用Paramspost等请求,提交数据包可以采用三种方式:form-date.urlenc ...
- 第二章、drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 (详细版)
目录 drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 Postman接口工具 drf框架 注册rest_framework drf框架风格 drf请求生命周期 请求模块 ...
- drf路由分发、解析/渲染模块配置、使用admin、自动序列化配置
目录 drf路由分发配置 解析模块配置 渲染模块配置 浏览器渲染打开 浏览器渲染关闭 结论 drf使用后台admin drf序列化模块 serializers.py: views.py:单查群查 测试 ...
随机推荐
- 【Spark】Day01-入门、模块组成、4种运行模式详解及配置、案例实操(spark分析过程)
一.概述 1.概念 基于内存的大数据分析计算引擎 2.特点 快速.通用.可融合性 3.Spark内置模块[腾讯8000台spark集群] Spark运行在集群管理器(Cluster Manager)上 ...
- flutter系列之:如丝般顺滑的SliverAppBar
目录 简介 SliverAppBar详解 SliverAppBar的使用 总结 简介 对于一个APP来说,肯定会有一个AppBar,这个AppBar一般包含了APP的导航信息等.虽然我们可以用一个固定 ...
- Scrum敏捷开发方法实践
前言 作者所在的公司在项目开发的过程中采用着当下互联网公司中流行的小步快跑开发策略,特别借鉴了敏捷开发中的迭代递增思想来指导项目的开发.我们经过对相关敏捷开发方法的调查研究,最终采用了Scrum敏 ...
- 服务器迁移遇到的bug
目前有个客户做了个下单系统,系统运行了太多的扩展了,但是又没有文档,我就想着能不能把服务器打包成镜像,然后用新服务直接使用?? 事实是完全OK的.服务器用的阿里云. 但是遇到一个bug,我目前还没解决 ...
- 2022年7月13日,第四组,周鹏,JS做计算器代码
代码不难,看了我前面笔记的应该能看懂. 没看?(= ̄ω ̄=)喵了个咪(๑‾᷅^‾᷅๑) 嫌弃你 还看啥,去看啊!要不直接复制代码吧!( ̄へ ̄)( ̄へ ̄)( ̄へ ̄) Document 0 / * - 7 ...
- 一文了解 Dubbo 3 配置工作原理
以下是一个 Dubbo 属性配置的例子 dubbo-spring-boot-samples ## application.properties # Spring boot application sp ...
- 「Python实用秘技12」像导入模块一样导入ipynb文件
本文完整示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/PythonPracticalSkills 这是我的系列文章「Python实用秘技」的第12 ...
- 算法学习笔记(5): 最近公共祖先(LCA)
最近公共祖先(LCA) 目录 最近公共祖先(LCA) 定义 求法 方法一:树上倍增 朴素算法 复杂度分析 方法二:dfs序与ST表 初始化与查询 复杂度分析 方法三:树链剖分 DFS序 性质 重链 重 ...
- Svelte框架实现表格协同文档
首先,从框架搭建上,本篇示例采用当下流行的前后端分离的开发方式,前端使用npm作为脚手架搭建Svelte框架. 后端使用Java的SpringBoot作为后端框架. 首先,介绍下在前端Svelte框架 ...
- flutter Error:Cannot run with sound null safety, because the following dependencies don't support
学习flutter新版本的路上,真的是一天一个新惊喜啊 今天遇到的坑是 Flutter 升级高版本后,运行和build 报错 Error: Cannot run with sound null saf ...