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渲染模块的Buffer

2. WebGL中的Buffer

以下大致是一个最简的WebGL绘制代码:

<canvas id="canvas"></canvas>
<script>
const vertexSource = `
attribute vec3 aPos; void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
`
const fragmentSource = `
void main()
{
gl_FragColor = vec4(1.0, 0.5, 0.2, 1.0);
}
`
const canvas = document.getElementById('canvas');
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
const gl = canvas.getContext('webgl2');
if (!gl) {
alert('WebGL not supported');
} const vertices = new Float32Array([
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
0.0, 0.5, 0.0,
]);
const vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); const vao = gl.createVertexArray();
gl.bindVertexArray(vao);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(0) const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexSource);
gl.compileShader(vertexShader); const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentSource);
gl.compileShader(fragmentShader); const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram); 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); </script>

其中,vbo是顶点缓冲对象(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 vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

WebGLBuffer 接口属于 WebGL API 的一部分,表示一个不透明的缓冲区对象,储存诸如顶点或着色之类的数据

WebGLBuffer 对象没有定义任何自己的方法或属性,且内容不能被直接访问。当使用 WebGLBuffer 对象时, WebGLRenderingContext 下的这些方法会很有用:

示例代码中:

createBuffer() 方法可创建并初始化一个用于储存顶点数据或着色数据的WebGLBuffer对象

bindBuffer(target, buffer) 方法将给定的WebGLBuffer绑定到目标,参数:

  • target

    GLenum (en-US) 指定绑定点 (target)。可能的值:

    • gl.ARRAY_BUFFER: 包含顶点属性的 Buffer,如顶点坐标,纹理坐标数据或顶点颜色数据。
    • gl.ELEMENT_ARRAY_BUFFER: 用于元素索引的 Buffer
  • buffer

    要绑定的 WebGLBuffer

bufferData(target, size, usage) 方法创建并初始化了 Buffer 对象的数据存储区,参数:

  • target

    GLenum (en-US) 指定 Buffer 绑定点(目标)。可取以下值:

    • gl.ARRAY_BUFFER: 包含顶点属性的 Buffer,如顶点坐标,纹理坐标数据或顶点颜色数据。
    • gl.ELEMENT_ARRAY_BUFFER: 用于元素索引的 Buffer
  • size

  • usage

    GLenum (en-US) 指定数据存储区的使用方法。可取以下值:

    • gl.STATIC_DRAW: 缓冲区的内容可能经常使用,而不会经常更改。内容被写入缓冲区,但不被读取。
    • gl.DYNAMIC_DRAW: 缓冲区的内容可能经常被使用,并且经常更改。内容被写入缓冲区,但不被读取。
    • gl.STREAM_DRAW: 缓冲区的内容可能不会经常使用。内容被写入缓冲区,但不被读取

以上大致就是WebGL中Buffer(VBO)的用法

3. Cesium中的Buffer

Cesium中,对WebGL的Buffer进行了封装:

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({
context: options.context,
bufferTarget: WebGLConstants.ARRAY_BUFFER,
typedArray: options.typedArray,
sizeInBytes: options.sizeInBytes,
usage: options.usage,
});
}; Buffer.createIndexBuffer = function (options) {
const buffer = new Buffer({
// ...
});
return buffer;
};

Buffer类的构造函数只是一次简单的封装,Buffer.createVertexBuffer函数可以更为快速的构建Buffer,搜索源码就会发现大多也是使用Buffer.createVertexBuffer创建Buffer,比如GeoJsonLoader.js

// ...
// Create GPU buffers
const positionBuffer = Buffer.createVertexBuffer({
typedArray: positionsTypedArray,
context: frameState.context,
usage: BufferUsage.STATIC_DRAW,
});
positionBuffer.vertexArrayDestroyable = false; const featureIdBuffer = Buffer.createVertexBuffer({
typedArray: featureIdsTypedArray,
context: frameState.context,
usage: BufferUsage.STATIC_DRAW,
});
featureIdBuffer.vertexArrayDestroyable = false; const indexBuffer = Buffer.createIndexBuffer({
typedArray: indicesTypedArray,
context: frameState.context,
usage: BufferUsage.STATIC_DRAW,
indexDatatype: indexDatatype,
});
indexBuffer.vertexArrayDestroyable = false;
// ...

使用Buffer.createVertexBuffer创建指定数据大小而数据未确定的VBO的例子:

// Example 1. Create a dynamic vertex buffer 16 bytes in size.
const buffer = Buffer.createVertexBuffer({
context : context,
sizeInBytes : 16,
usage : BufferUsage.DYNAMIC_DRAW
});

使用Buffer.createVertexBuffer创建数据确定的VBO的例子:

// Example 2. Create a dynamic vertex buffer from three floating-point values.
// The data copied to the vertex buffer is considered raw bytes until it is
// interpreted as vertices using a vertex array.
const positionBuffer = buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0]),
usage : BufferUsage.STATIC_DRAW
});

使用Buffer.createIndexBuffer创建指定数据大小而数据未确定的IBO的例子:

// Example 1. Create a stream index buffer of unsigned shorts that is
// 16 bytes in size.
const buffer = Buffer.createIndexBuffer({
context : context,
sizeInBytes : 16,
usage : BufferUsage.STREAM_DRAW,
indexDatatype : IndexDatatype.UNSIGNED_SHORT
});

使用Buffer.createIndexBuffer创建数据确定的IBO的例子:

// Example 2. Create a static index buffer containing three unsigned shorts.
const buffer = Buffer.createIndexBuffer({
context : context,
typedArray : new Uint16Array([0, 1, 2]),
usage : BufferUsage.STATIC_DRAW,
indexDatatype : IndexDatatype.UNSIGNED_SHORT
});

此外,Buffer封装的函数有:

Buffer.prototype.copyFromArrayView = function (arrayView, offsetInBytes)
Buffer.prototype.copyFromBuffer = function (
readBuffer,
readOffset,
writeOffset,
sizeInBytes
)
Buffer.prototype.getBufferData = function (
arrayView,
sourceOffset,
destinationOffset,
length
)
Buffer.prototype.isDestroyed
Buffer.prototype.destroy

4. 参考资料

[1]Cesium原理篇:6 Renderer模块(1: Buffer) - fu*k - 博客园 (cnblogs.com)

[2]WebGLRenderingContext - Web API 接口参考 | MDN (mozilla.org)

[3]Cesium渲染模块之概述 - 当时明月在曾照彩云归 - 博客园 (cnblogs.com)

Cesium渲染模块之Buffer的更多相关文章

  1. Cesium原理篇:6 Renderer模块(1: Buffer)

    刚刚结束完地球切片的渲染调度后,打算介绍一下目前大家都很关注的3D Tiles方面的内容,但发现要讲3D Tiles,或者充分理解它,需要对DataSource,Primitive要有基础,而这要求对 ...

  2. Cesium原理篇:6 Renderer模块(1: Buffer)【转】

    https://www.bbsmax.com/A/n2d9P1Q5Dv/ 刚刚结束完地球切片的渲染调度后,打算介绍一下目前大家都很关注的3D Tiles方面的内容,但发现要讲3D Tiles,或者充分 ...

  3. (原)Unreal渲染模块 管线 - 着色器(1)

    @author: 白袍小道 转载悄悄说明下 随缘查看,施主开心就好 说明: 本篇继续Unreal搬山部分的渲染模块的Shader部分, 主要牵扯模块RenderCore, ShaderCore, RH ...

  4. (原)Unreal渲染模块 管线 - 程序和场景查询

    @author: 白袍小道 查看随意,转载随缘     第一部分: 这里主要关心加速算法,和该阶段相关的UE模块的结构和组件的处理. What-HOW-Why-HOW-What(嘿嘿,老规矩) 1.渲 ...

  5. (原)Unreal渲染模块 源码和实例分析说明

    @author:白袍小道 说明 1.由于小道就三境武夫而已,而UE渲染部分不仅管理挺大,而且牵扯技术和内容驳杂,所以才有这篇梳理. 2.尽量会按书籍和资料,源码,小模块的调试和搬山(就是敲键盘)..等 ...

  6. (原)Unreal 渲染模块 渲染流程

    @author:白袍小道 浏览分享随缘,评论不喷亦可.     扯淡部分: 在temp中,乱七八糟的说了下大致的UE过程.下面我们还是稍微别那么任性,一步步来吧.     UE渲染模块牵扯到场景遍历. ...

  7. (原)Unreal 渲染模块引言Temp

            @author:白袍小道     引言 本文只在对Unreal渲染模块做一些详细的理解,务求能分析出个大概. 其中框架的思想和实现的过程,是非常值得学习和推敲一二的. 涉及资源系统,材 ...

  8. Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基础文件配置,Web框架的本质,服务器程序和应用程序(wsgiref服务端模块,jinja2模板渲染模块)的使用

    Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基 ...

  9. DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render

    DRF框架    全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...

  10. drf框架 - 请求模块 | 渲染模块

    Postman接口工具 官方 https://www.getpostman.com/ get请求,携带参数采用Params​post等请求,提交数据包可以采用三种方式:form-date.urlenc ...

随机推荐

  1. python安装过程

    1.在官网下载,点击进入安装包. 2.把Add勾上,会自动配置环境变量. 3,这些是要下载的东西,要全部勾上. 4.这里特别注意路径,把路径改成自己想放的盘里面. 5.配置环境变量,在此电脑搜索 编辑 ...

  2. “It is required that your private key files are NOT accessible by others. This private key will be ignored.”

    Windows Terminal 通过密钥登录远程vps时提示: "It is required that your private key files are NOT accessible ...

  3. Redis缓存何以一枝独秀?——从百变应用场景与热门面试题中感受下Redis的核心特性与使用注意点

    大家好,又见面了. 本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面.如果感兴趣,欢迎关注以获取后续更新. 作为<深入理解缓存原理与实战设计 ...

  4. P5683 [CSP-J2019 江西] 道路拆除

    简要题意 给你一个 \(m\) 条边 \(n\) 个点的无向图.你需要去掉一些边,使得 \(1 \to s_1,1 \to s_2\) 连通,且 \(1 \to s_1\) 的最短路径长度小于 \(t ...

  5. iOS开发小结 - 通过PUT请求上传数据

    一般服务器上传数据一般都是用POST请求,这样通过AFNetworking的POST请求稳稳的,但是有一天遇到一个问题,服务器上传数据用的是PUT请求,发现用AFNetworking并不是那么好用,今 ...

  6. 图文并茂解决Client does not support authentication protocol requested by server; consider upgrading MySQL

    今天服务器部署node.js+mysql,调用接口报错ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protoc ...

  7. 在windows系统下用vscode构造shell脚本IDE

    1.基础环境搭建 安装Visual Studio Code(VScode ) 下载地址:https://code.visualstudio.com/Download 下载完双击文件,选择路径安装即可, ...

  8. 【Oculus Interaction SDK】(六)实体按钮 && 按压交互

    前言 这篇文章是[Oculus Interaction SDK]系列的一部分,如果发现有对不上的对方,可以回去翻看我之前发布的文章,或在评论区留言.如果文章的内容已经不适用于新版本了,也可以直接联系我 ...

  9. 洛谷p5723

    1 #include<bits/stdc++.h> 2 using namespace std; 3 int z(int a) 4 { 5 if(a==2) return 1; 6 if( ...

  10. 【HMS Core】机器学习服务助力APP快速集成图像分割与上传功能

    ​ 1.介绍 总览 机器学习服务(ML Kit)提供机器学习套件,为开发者使用机器学习能力开发各类应用,提供优质体验.得益于华为长期技术积累,ML Kit为开发者提供简单易用.服务多样.技术领先的机器 ...