网站做图分辨率,建设电影网站选服务器怎么选,网站系统平台建设,外贸网站源码phpPython微信订餐小程序课程视频
https://blog.csdn.net/m0_56069948/article/details/122285951
Python实战量化交易理财系统
https://blog.csdn.net/m0_56069948/article/details/122285941 目录* 回顾 预备知识#xff1a;指令 预备知识#xff1a;通道
1. 生成并执行…Python微信订餐小程序课程视频
https://blog.csdn.net/m0_56069948/article/details/122285951
Python实战量化交易理财系统
https://blog.csdn.net/m0_56069948/article/details/122285941 目录* 回顾 预备知识指令 预备知识通道
1. 生成并执行指令 1.1. Primitive 生成指令1.2. Context 对象负责执行 WebGL 底层代码 2. 多段视锥体技术3. 指令对象的转移 筛选可见集 4. 本篇总结 回顾
书接上文Scene.js 模块内的 render 函数会将控制权交给 WebGL执行 CesiumJS 自己封装的指令对象画出每一帧来。
模块内的 render 函数首先会更新一批状态信息譬如帧状态、雾效、Uniform 值、通道状态、三维场景中的环境信息等然后就开始更新并执行指令调用的是 Scene 原型链上的 updateAndExecuteCommands 方法。
整个过程大致的调用链是这样的function 关键字简写为 fn
[Module Scene.js]
- fn render()- Scene.prototype.updateAndExecuteCommands()- fn executeCommandsInViewport()- fn updateAndRenderPrimitives()[Module Primitive.js]- fn createCommands()- fn updateAndQueueCommands()- fn executeCommands()- fn executeCommand()
本篇讲解的是从 Scene 原型链上的 updateAndExcuteCommands() 方法开始期间 Scene 中的 Primitives 是如何创建指令又最终如何被 WebGL 执行的。
这个过程涉及非常多细节代码但是为了快速聚焦整个过程本篇先介绍两个 CesiumJS 封装的概念指令和通道。
预备知识指令
WebGL 是一种依赖于“全局状态”的绘图 API面向对象特征比较弱为了修改全局状态上的顶点数据、着色器程序、帧缓冲、纹理等“资源”必须通过 gl.XXX 函数调用触发全局状态的改变。
而图形编程基础提出的渲染管线、通道等概念偏向于面向对象显然 WebGL 这种偏过程的风格需要被 JavaScript 运行时引擎封装。
CesiumJS 将 WebGL 的绘制过程也就是行为封装成了“指令”不同的指令对象有不同的用途。指令对象保存的行为具体就是指由 Primitive 对象不一定全是 Primitive生成的 WebGL 所需的数据资源缓冲、纹理、唯一值等以及着色器对象。数据资源和着色器对象仍然是 CesiumJS 封装的对象而不是 WebGL 原生的对象这是为了更好地与 CesiumJS 各种对象结合去绘图。
CesiumJS 有三类指令
DrawCommand 绘图指令ClearCommand 清屏指令ComputeCommand 计算指令
绘图指令最终会把控制权交给 Context 对象根据自身的着色器对象绘制自己身上的数据资源。
清屏指令比较简单目的就是调用 WebGL 的清屏函数清空各类缓冲区并填充清空后的颜色值依旧会把控制权传递给 Context 对象。
计算指令则借助 WebGL 并行计算的特点将指令对象上的数据在着色器中编码、计算、解码最后写入到输出缓冲通常是帧缓冲的纹理上同样控制权会给到 Context 对象。
预备知识通道
一帧是由多个通道顺序绘制构成的在 CesiumJS 中通道英文单词是 Pass。
既然通道的绘制是有顺序的其顺序保存在 Renderer/Pass.js 模块导出的冻结对象中目前1.92版本有 10 个优先顺序等级
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,OVERLAY: 9,NUMBER\_OF\_PASSES: 10,
}
以上为例第一优先被绘制的指令是环境ENVIRONMENT: 0方面的对象、物体。而不透明OPAQUE: 7的三维对象的绘制指令则要先于透明TRANSLUCENT: 8物体被执行。
CesiumJS 会在每一帧即将开始绘制前对所有已经收集好的指令根据通道进行排序实现顺序绘制下文会细谈。
1. 生成并执行指令
原型链上的 updateAndExecuteCommands 方法会做模式判断我们一般使用的是三维模式SceneMode.SCENE3D所以只需要看 else if 分支即可也就是
executeCommandsInViewport(true, this, passState, backgroundColor);
此处this 就是 Scene 自己。
executeCommandsInViewport() 是一个 Scene.js 模块内的函数这个函数比较短对于当前我们关心的东西只需要看它调用的 updateAndRenderPrimitives() 和最后的 executeCommands() 函数调用即可。
1.1. Primitive 生成指令
[Module Scene.js]
- fn updateAndRenderPrimitives()[Module Primitive.js]- fn createCommands()- fn updateAndQueueCommands()
Scene.js 模块内的函数 updateAndRenderPrimitives() 负责更新 Scene 上所有的 Primitive。
期间控制权会通过 PrimitiveCollection 转移到 Primitive 类或者有类似结构的类譬如 Cesium3DTileset 等上令其更新本身的数据资源根据情况创建新的着色器并随之创建 绘图指令最终在 Primitive.js 模块内的 updateAndQueueCommands() 函数排序、并推入帧状态对象的指令列表上。
1.2. Context 对象负责执行 WebGL 底层代码
[Module Scene.js]
- fn executeCommands()
- fn executeCommand() // 收到 Command 和 Context[Module Context.js]- Context.prototype.draw()
另一个模块内的函数 executeCommands() 则负责执行这些指令中间还有一些小插曲下文再提。
此时上文的“通道”再次起作用此函数内会根据 Pass 的优先顺序依次更新唯一值状态UniformState然后下发给 executeCommand() 函数注意少了个s以具体的某个指令对象以及 Context 对象。 除了 executeCommand() 函数外Scene.js 模块内仍还有其它类似的函数例如 executeIdCommand() 负责执行绘制 ID 信息纹理的指令executeTranslucentCommandsBackToFront() / executeTranslucentCommandsFrontToBack() 函数负责透明物体的指令等。甚至在 Scene 对象自己的属性中就有清屏指令字段会在 executeCommands() 函数中直接执行不经过上述几个执行具体指令的函数。 Context 对象是对 WebGL(2)RenderingContext 等 WebGL 原生接口、参数的封装所有指令对象最终都会由其进行拆包装、组装 WebGL 函数调用并执行绘图、计算、清屏见上文介绍的预备知识指令。
2. 多段视锥体技术
先介绍一个概念WebGL 中的深度。
简单的说屏幕朝里三维物体的前后顺序就是深度。CesiumJS 的深度非常大即使不考虑远太空只考虑地球表面附近的范围WebGL 的数值范围也不太够用。聪明的前辈们想到了使用对数函数压缩深度的值域因为一个非常大的数字只需取其对数很快就能小下来。
Scene 对象上有一个可读可写访问器 logarithmicDepthBuffer它指示是否启用对数深度。
现在CesiumJS 通常使用的就是对数深度。
对数深度解决的不仅仅只是普通深度值值域不够的问题还解决了不支持对数深度技术之前使用的多段视锥技术问题。
再次简单的说多段视锥技术将视锥体由远及近切成多个段保证了相机近段的指令足够多以保证效果远段尽量少满足性能。
你在 Scene.js 模块中的 executeCommands() 函数的最后能找到一个循环体
// Execute commands in each frustum in back to front order
let j;
for (let i 0; i numFrustums; i) {// ...
}
打开调试工具很容易击中这个断点查看 numFrustums 变量的值有启用对数深度的 CesiumJS 程序一般 numFrustums 都是 1。
3. 指令对象的转移
在本文第 1 节中详细说明了指令对象的生成与被执行。
上述其实忽略了很多细节现在捡起来说。
指令对象在 Primitive或类似的类生成后由 模块内的 updateAndQueueCommands() 函数排序并推入帧状态对象的指令列表上
// updateAndQueueCommands 函数中函数接收来自 Scene 逐级传入的帧状态对象 -- frameState
const commandList frameState.commandList;
const passes frameState.passes;
if (passes.render || passes.pick) {// ... 省略部分代码commandList.push(colorCommand);
}
frameState.commandList 就是个普通的数组。
而在执行时却是从 View 对象上的 frustumCommandsList 上取的指令
// Scene.js 模块的 executeCommands 函数中const frustumCommandsList view.frustumCommandsList;
const numFrustums frustumCommandsList.length;let j;
for (let i 0; i numFrustums; i) {const index numFrustums - i - 1;const frustumCommands frustumCommandsList[index];// ...// 截取不透明物体的通道指令执行代码片段us.updatePass(Pass.OPAQUE);commands frustumCommands.commands[Pass.OPAQUE];length frustumCommands.indices[Pass.OPAQUE];for (j 0; j length; j) {executeCommand(commands[j], scene, context, passState);}// ...
}
其中下发给 executeCommand() 函数的 commands[j] 参数就是具体的某个指令对象。
所以这两个过程之间是怎么做指令对象传递的
答案就在 View 原型链上的 createPotentiallyVisibleSet 方法中。
筛选可见集
View 对象是 Scene、Camera 之间的纽带负责“眼睛”与“世界”之间信息的处理即视图。
View 原型链上的 createPotentiallyVisibleSet 方法的作用就是把 Scene 上的计算指令、覆盖物指令帧状态上的指令列表根据 View 的可见范围做一次筛选减少要执行指令个数提升性能。
具体来说就是把分散在各处的指令筛选后绑至 View 对象的 frustumCommandsList 列表中借助 View.js 模块内的 insertIntoBin() 函数完成
// View.js 模块内function insertIntoBin(view, scene, command, commandNear, commandFar) {// ...const frustumCommandsList view.frustumCommandsList;const length frustumCommandsList.length;for (let i 0; i length; i) {// ...frustumCommands.commands[pass][index] command;// ...}// ...
}
这个函数内做了对指令的筛选判断。
4. 本篇总结
本篇调查清楚了 Scene 对象上各种三维物体是如何绘制的即借助 指令 对象保存待绘制的信息最后交由 Context 对象完成 WebGL 代码的执行。
期间发生了指令的分类和可见集的筛选篇幅原因CesiumJS 在这漫长的渲染过程中还做了很多细节的事情。
不过Cesium 的三维物体的渲染架构就算讲完了。
接下来则是另两个比较头痛的话题
地球的渲染架构瓦片四叉树具备创建指令的各路数据源Entity、DataSource、Model、Cesium3DTileset等
指令和通道的概念仍然会继续使用敬请期待。 回顾 预备知识指令 预备知识通道 1. 生成并执行指令 1.1. Primitive 生成指令 1.2. Context 对象负责执行 WebGL 底层代码 2. 多段视锥体技术 3. 指令对象的转移 筛选可见集 4. 本篇总结 __EOF__ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-16LUkhXl-1649652132633)(https://blog.csdn.net/onsummer)]四季留歌 - 本文链接 https://blog.csdn.net/onsummer/p/16129435.html
关于博主 评论和私信会在第一时间回复。或者直接私信我。版权声明 本博客所有文章除特别声明外均采用 BY-NC-SA 许可协议。转载请注明出处声援博主 如果您觉得文章对您有帮助可以点击文章右下角**【[推荐](javascript:void(0)】**一下。