Cesium 高性能扩展之DrawCommand(三):显隐和点选

欢迎关注微信公号【三维网格3D】,第一时间获取最新文章

DrawCommand 是 Cesium 渲染器的核心类,常用的接口 Entity、Primitive、Cesium3DTileSet,以及地形和影像的渲染等等,底层都是一个个 DrawCommand 完成的。在进行扩展开发、视觉特效提升、性能优化、渲染到纹理(RTT),甚至基于 Cesium 封装自己的开发框架,定义独家数据格式等等,都需要开发人员对 DrawCommand 熟练掌握。而这部分接口,Cesium 官方文档没有公开,网上的相关资料也比较少,学习起来比较困难,所以接下来我们用几期文章,由浅入深,实用为主,力求全面地介绍 DrawCommand 及相关类的运用。

第一次被关注我们的小伙伴催更,还是挺开心的😂,公司事务略忙,只有深夜码字来赶稿了~那么本篇我们就按照计划往下写,介绍自定义Primitive的显隐控制,以及如何支持scene.pick,实现要素拾取查询。

1、显隐控制

从前面两篇的代码看,显隐控制是非常简单的,我们只需要在update方法的开头加入显隐判断,如果隐藏则直接退出,否则继续。

考虑一下,如果我们将多个要素的几何体合并成一个几何体,以达到减少绘图批次(DrawCommand的数量)提升性能的目的,这种情况下,上述方法将会同时显示或者隐藏这些要素,那么该如何控制其中任一要素的显隐呢?

参考Cesium的其他Primitive类,会发现他们为每一个顶点创建了一个batchId或者a_batchId属性,这个属性非常重要,除了可以用于控制显隐外,在3D Tiles样式引擎、要素拾取查询(pick)等都起到关键作用。

这里简单介绍基于batchId的显隐控制实现思路:

为每一个要素创建batchId,从0开始编号;

为要素几何体创建batchId顶点属性,并将batchId值逐个写入顶点属性数组;

合并所有要素几何体;

创建一个二维数组类型的纹理贴图,宽度等于要素数量,高度为1,用0和1表示要素隐藏或者显示,写入纹理数据;

在shader中根据batchId并计算uv,从显隐纹理获取要素的显隐标记,如果小于1则discard;

当某个要素显隐发生变化时,更新显隐纹理。

目前我们先不要想那么复杂,等掌握了更多技能,需要设计这么复杂的自定义Primitve的时候,自然能理解并参考Cesium的代码来实现这一显隐控制方法。

2、支持pick实现点选

要素拾取查询(Pick),是3D交互的重要基础,想象一下一个3D应用,所有图形要素怎么点击都没有反应,那它跟一个视频播放器就没有什么两样了~

Cesium提供了统一的要素拾取查询机制,拾取API封装在Cesium.Scene中,前面我们介绍3D描边等后期处理时就曾使用过,非常简单。


那么如果让我们的自定义Primitive能够被scene.pick点击拾取到呢?

2.1、context创建pickId

2.2、shader声明pickId变量

这里可以pickId变量类型有两种:uniform和varying。

uinform:如果DrawCommand绘制的是单一要素,所绘制的内容就是一个整体,则使用uniform,所有顶点的pickId颜色是一样的,通过uniformMap来传递;

varying:如果绘制的是多个要素,绘制内容可能分为多个部件,只是合并为一个批次来渲染,可能每个部件需要能够被单独点击拾取,则使用varying,需要将每一个部件要素的pickId颜色写入对应的几何顶点属性,顶点着色器接收颜色值,并通过varying传递到偏远着色器。

2.2.1、uniform类pickId

2.2.2、 varying类pickId

2.2.3、Cesium对DrawCommand的后续加工

大家可能很好奇,为什么pickId变量,只是声明,却没有见到具体的使用,怎么能实现点击拾取呢?

这个问题,大家不妨在绘制出结果后(延迟一段时间)打印出DrawCommand对象看看:

我们接着展开看看pickCommand._shaderProgram._vertexShaderText:

Cesium为pick操作创建了一个新的DrawCommand副本pickCommand,并且基于我们的shader进行加工处理,在新的main函数使用了我们声明的pickId变量。

同时大家可以看到,不止多了一个pickCommand,还增加了好几个其他DrawCommand副本,说明我们创建好的DrawCommand并没有直接进入渲染阶段,而是要经过Cesium渲染器进行加工处理,才最终交付执行渲染。

想一下,如果我们开启了阴影那么会不会又增加一个副本呢?这个问题我们留到下一篇来探讨。

2.3、传递pickId颜色

与2.2节相对应,如果pickId变量为uniform类,则通过unformMap传递其颜色,如果为varying则需要修改几何体,增加pickId颜色相关的顶点属性。

2.3.1、uniformMap传递

2.3.2、顶点属性传递

这种情况下,2.1创建的pickId就不够用了,我们需要为每一个要素的几何体创建一个pickId。我们定一个方法,来处理每一个要素的几何体。

2.4、drawCommand指定pickId变量

2.5、释放pickId

需要注意,当我们不需要pickId或者drawCommand释放或者整个Primitive释放时,一定要释放pickId,否则将会出现内存泄漏,因为我们会将primitive对象绑定到pickId,这个pickId不释放的话,会一直保存在context的缓存里,直到整个程序消亡。

下面是完整的drawCommandd释放方法,包含了pickId的释放。

3、点选示例及效果视频


uniform

有没有发现,当我们加入pickId之后,不但点击拾取查询功能实现了,包括后期处理高亮也自然支持了,这是因为Cesium后期处理的要素选择也是基于pickId实现的。

本篇到此结束,如果觉得有用,不妨点赞+分享,让更多小伙伴一起来交流学习吧!

下一篇我们将介绍阴影(shadows)和实例化(instancing),敬请期待!

欢迎关注微信公号【三维网格3D】,第一时间获取最新文章

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,295评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,928评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,682评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,209评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,237评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,965评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,586评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,487评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,016评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,136评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,271评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,948评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,619评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,139评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,252评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,598评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,267评论 2 358

推荐阅读更多精彩内容