用osgEarth实现Cesium的后处理特效(1)
写这个博客的初衷:开源的数字地球发展,从最开始的worldWind(纯正的NASA血统,大约从2006年开始流行,当我还是学生的时候用这个框架实现了中石油的林火蔓延模拟系统,以及在这个球上实现救援应急响应的模拟,当时拿了集团的一个奖项,所以我个人对这个版本情有独钟,从软件架构上将,NASA的工作确实非常了不起,整个软件的框架层次分明,而又十分简洁,目前的cesium版本里面能还能找到worldwind的影子,可惜的是JAVA语言开发的这个版本没有得到维护,全网也找不到几个用wwd来开发应用的人,原因可能是JAVA在桌面端的萎缩,JAVA实现OpenGL的特效这方面有限制,当WebGL刚推出的时候,我给NASA开发小组的大佬写了个邮件,咨询是否有计划开发下一代的WebGL版本,得到了大牛的回复,大意是WEB端也需要下载js文件,一样的耗费时间,后来NASA推出了ActiveX 版本的WWJ, 只不过响应者寥寥),到第二代数字地球(OSGEarth大约从2010年以后流行开来,这个版本基于OSG开发的,总体感觉是,软件的架构太复杂。因为OSG本身是通用的三维引擎软件,并非为数字地球量身定制,这个引擎本身就存在过度设计、过度包装的问题,随便在代码里下一个断点,函数调用栈几十层,看得人眼花缭乱,感觉这个软件的作者在抖小聪明,虽然这样评价要得罪部分OSG粉丝)。目前的CESIUM软件大行其道,如日中天,从项目案例上看,NASA已经完全放弃自家的WWJ, 也转移到CESIUM平台做开发。CESIUM社区的繁荣和OSGEARTH社区的没落形成了鲜明的对比,作为一位怀旧的技术人员,我花了点时间将CESIUM后处理特效的炫目效果移植到OSGEARTH,做一个尝试。于是有了这几篇博文。
PostProcessStage的效果:
cesium 中shader的管理机制:
定义一个shaderSouce, option参数里面重要的两个参数 defines 和 sources. defines 定义的shader里面的宏,我猜应该是对shader里面的'#define' 做了一种替换。而sources应该是各种vs fs 的代码段。
function ShaderSource(options) {options = defaultValue(options, defaultValue.EMPTY_OBJECT);var pickColorQualifier = options.pickColorQualifier;//>>includeStart('debug', pragmas.debug);if (defined(pickColorQualifier) &&pickColorQualifier !== "uniform" &&pickColorQualifier !== "varying") {throw new DeveloperError("options.pickColorQualifier must be 'uniform' or 'varying'.");}//>>includeEnd('debug');this.defines = defined(options.defines) ? options.defines.slice(0) : [];this.sources = defined(options.sources) ? options.sources.slice(0) : [];this.pickColorQualifier = pickColorQualifier;this.includeBuiltIns = defaultValue(options.includeBuiltIns, true);
}
通过上面的代码,定义了两个shaderSource, 只是它们还没有被编译和链接,接着看下面的代码段,
var vs = new ShaderSource({defines: defines.concat("SKY_FROM_SPACE"),sources: [SkyAtmosphereCommon, SkyAtmosphereVS],});var fs = new ShaderSource({defines: defines.concat("SKY_FROM_SPACE"),sources: [SkyAtmosphereCommon, SkyAtmosphereFS],});
定义出两个具体的shader。
this._spSkyFromSpace = ShaderProgram.fromCache({context: context,vertexShaderSource: vs,fragmentShaderSource: fs,});
这里才是正在创建经过编译和链接的shader. vs 和 fs 总是成双出现。从名字,不难猜出Cesium 对各种shader做了缓存。继续深入到ShaderProgram.fromCache的底层代码
ShaderCache.prototype.getShaderProgram = function (options) {// convert shaders which are provided as strings into ShaderSource objects// because ShaderSource handles all the automatic including of built-in functions, etc.var vertexShaderSource = options.vertexShaderSource;var fragmentShaderSource = options.fragmentShaderSource;var attributeLocations = options.attributeLocations;if (typeof vertexShaderSource === "string") {vertexShaderSource = new ShaderSource({sources: [vertexShaderSource],});}if (typeof fragmentShaderSource === "string") {fragmentShaderSource = new ShaderSource({sources: [fragmentShaderSource],});}var vertexShaderText = vertexShaderSource.createCombinedVertexShader(this._context);var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader(this._context);var keyword =vertexShaderText + fragmentShaderText + JSON.stringify(attributeLocations);var cachedShader;if (defined(this._shaders[keyword])) {cachedShader = this._shaders[keyword];// No longer want to release this if it was previously released.delete this._shadersToRelease[keyword];} else {var context = this._context;var shaderProgram = new ShaderProgram({gl: context._gl,logShaderCompilation: context.logShaderCompilation,debugShaders: context.debugShaders,vertexShaderSource: vertexShaderSource,vertexShaderText: vertexShaderText,fragmentShaderSource: fragmentShaderSource,fragmentShaderText: fragmentShaderText,attributeLocations: attributeLocations,});cachedShader = {cache: this,shaderProgram: shaderProgram,keyword: keyword,derivedKeywords: [],count: 0,};// A shader can't be in more than one cache.shaderProgram._cachedShader = cachedShader;this._shaders[keyword] = cachedShader;++this._numberOfShaders;}++cachedShader.count;return cachedShader.shaderProgram;
};
以上代码,从各种 shaderSource的合并,计算出一个keyWord(为啥不搞个hash?), 然后根据keyword 在缓存里面查找是不是已经有这样的shader,如果有的话就直接用这个已有的shader返回。否则创建一个新的ShaderProgram, 并且放入缓存,以备下次查找。
Cesium中的shader:
基本顶点shader
globe._surfaceShaderSet.baseVertexShaderSource = new ShaderSource({sources: [GroundAtmosphere, GlobeVS],defines: defines,});globe._surfaceShaderSet.baseFragmentShaderSource = new ShaderSource({sources: fragmentSources,defines: defines,});
关于大气的shader
var vs = new ShaderSource({defines: defines.concat("SKY_FROM_SPACE"),sources: [SkyAtmosphereCommon, SkyAtmosphereVS],});var fs = new ShaderSource({defines: defines.concat("SKY_FROM_SPACE"),sources: [SkyAtmosphereCommon, SkyAtmosphereFS],});
天空盒的shader
var fs = new ShaderSource({defines: [useHdr ? "HDR" : ""],sources: [SkyBoxFS],});command.shaderProgram = ShaderProgram.fromCache({context: context,vertexShaderSource: SkyBoxVS,fragmentShaderSource: fs,attributeLocations: this._attributeLocations,});
用osgEarth实现Cesium的后处理特效(1)相关推荐
- 虚幻UE4的后处理特效介绍
虚幻UE4提供了后处理特效的功能,可以实现景深,光溢出,色调调整,饱和度等等.要使用虚幻4的后处理,就一定要用到PostProcessVolumn,这是一种特殊的体积,可以放置在场景中的任何位置. ...
- 虚幻UE4的后处理特效介绍 http://www.52vr.com/thread-31215-1-1.html
转载 虚幻UE4提供了后处理特效的功能,可以实现景深,光溢出,色调调整,饱和度等等.要使用虚幻4的后处理,就一定要用到PostProcessVolumn,这是一种特殊的体积,可以放置在场景中的任何位置 ...
- Urp下自定义特效管线和后处理特效实现
一.如何获得颜色缓冲 网上搜索Unity的后处理或者获得屏幕缓冲,大部分会提到用grabpass到一张指定纹理上或者写一个后处理脚本挂在摄像机上.但是这种方式在Urp管线下已经不生效了.urp取消了默 ...
- Cesium 3dtiles 渐变特效 vite-plugin-cesium版
Cesium 3dtiles 渐变特效 vite-plugin-cesium版 源码 结语 源码 // An highlighted block import * as Cesium from &qu ...
- cesium fog雾特效参数设置
关闭HDR 可以增加雾的曝光强度 一.开启雾设置参数: 二.GlobeFS.glsl 中HDR影响雾特效的代码 #if defined(FOG) || defined(GROUND_ATMOSPHER ...
- Unity3D图像后处理特效——Grayscale image effect
Grayscale is a simple image effect that changes colors to grayscale by default. It can also use a Te ...
- Unity3d展厅模型预处理UV拆分光影烘焙材质及后处理与特效制作基本流程【2020】
应很多读者的要求,本文小姐姐将以一个用户的展厅VR场景为例,详细讲解Unity3d的VR开发在美工阶段的模型预处理.UV2拆分.贴图优化.光影烘焙.后处理与特效制作以及最终作品优化的基本方法和流程 ...
- 屏幕后处理——Bloom
来自于<Unity Shader 入门精要>书本的学习 先上图 代码分3部分 1.PostEffectsBase.cs using System.Collections; using Sy ...
- system volume information是什么文件_如何扩展Unity URP的后处理Volume组件
Unity在更新到Unity2019.4之后,大家或许已经发现,在使用URP(通用渲染管线)的情况下,Unity原来的Post Processing插件好像不起效了.原来Unity在Unity2019 ...
最新文章
- 核心(Core) Javascript 学习手记
- seo说_百度指数看世间沉浮_如何快速排名-互点快速排名_网站关键词排名常见问题 - 搜狗快速排名...
- 清除Windows Server 2008上的休眠文件”hiberfil.sys”
- ACM入门之【离散化】
- odoo13中的模型类(模型属性、字段属性、字段类型)
- Python连接DM8数据库
- RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.0 版本强势发布
- C#多线程编程系列(二)- 线程基础
- ribbon设置权重_spring cloud gateway+ribbon 组合指定版本权重分流(简易灰度发布实现)...
- 如何消除选定TextBox后的光标但又不失去焦点。
- ros melodic控制真实机械臂之等周期输出插补点
- Nginx configure
- [vmware]解析单一GHO文件如何安装操作系统
- eharts散点图 调整点的颜色和大小。
- 类似于android短信校验码的demo
- 蓝牙耳机买什么品牌好一些?2022蓝牙耳机品牌排行榜10强
- Eclipse超棒的主题,你不能错过!
- 高阳墙绘 墙体彩绘 手绘壁画赏析
- html修改img图片颜色,教你如何用CSS修改图片颜色
- TEB算法2-teb参数说明及调试小记
热门文章
- 做Linux背锅2年,我总结了这六类好习惯和30个血的教训
- Spark机器学习(9):FPGrowth算法
- Ajax异步XMLHttpRequest对象
- 悠然乱弹:我的开源观
- LINUX TOP,不是这样玩地!!!
- 网络规划与设计讨论会(第3期)
- Leangoo敏捷看板管理 6.3.8
- 社会内卷的真正原因?华为内部论坛的这篇雄文火了
- 海外名校毕业!好不容易凭借超强的面试能力+算法入职的谷歌新员工被批干活太慢,委屈得要哭!作为职场新人该怎么办?...
- ABA问题的本质及其解决办法