1. 程式人生 > >CesiumLab V1.4 分類3dtiles生成(傾斜單體化、樓層房間交互)

CesiumLab V1.4 分類3dtiles生成(傾斜單體化、樓層房間交互)

垂直 存儲 dac position ade bim 相機 ext dea

我記得我是寫過一篇關於傾斜單體化的簡書文章的,但是現在找不到了。不過找不到也好,就讓他隨風逝去吧,因為當時我寫那篇文章的時候,就發現了cesium實際是有另一種更高效的單體化。就下面這個示例
https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/index.html?src=3D%20Tiles%20Photogrammetry%20Classification.html
技術分享圖片
sandcastle中分類3dtiles
我們來看看他的代碼:技術分享圖片
示例代碼
第1 ~ 第9行 添加了大樓的3dtiles,並且相機定位過去。
第12~第19行添加一個分類3dtiles。這裏面最關鍵的是第14行,設置了一個classificationType 屬性。
第22~最後一行 實際是添加這個分類3dtiles,但是沒有設置classificationType ,用來和第二個對比。我們切換之後是這樣的

技術分享圖片
沒有設置classificationType 的默認3dtiles效果
從這個示例,我們得知,cesium可以使用一個3dtiles B 對 另一個3dtiles A 進行分類,並且使用可以使B包含A的部分高亮和鼠標交互。至於這種緊貼模型的效果怎麽出來的,不是今天的重點,可以提一句,其實就是經典的shadow volumn 陰影的渲染方法。
類比我們曾經傾斜單體化,我們所需要的就是點擊傾斜模型A的一些部分(比如一棟大樓)能單獨高亮顯示,並且附加gis屬性。那麽我們前提需要兩個3dtiles:第一個就是傾斜模型的3dtiles A,這個ok,使用cesiumlab的傾斜處理工具很容易就處理了。第二個就是這個攜帶gis屬性的分類3dtiles B,下來我們就要重點說說這個分類3dtiles如何生成。

我們這個分類3dtiles有如下的特點:
1, 考慮到我們一般是用來分割建築物 或者 建築物的樓層,那麽這個分類3dtiles必然是個柱體,也就是說側面是垂直的,頂面是平行地表的。
2, 考慮到shadow volumn算法的要求,陰影體必須是包圍的,所以我們必須構造一個封閉的柱體,也就是需要底面。
我們再來看這個需求,很簡單,只要我們有了建築輪廓矢量 以及 這個矢量面的 底面高度 和 頂面高度,就可以構造這個3dtiles。所以我就在我的另一個工具,建築物矢量面工具中擴展了這個功能
技術分享圖片
這個工具
技術分享圖片
增加了構造底面和底面高度的功能
用這個工具,我們來生成一個分類大雁塔3dtiles(參數渲染見上圖,數據還是上次做大雁塔的單體化示例矢量數據)
技術分享圖片
矢量面工具生成的樓層3dtiles
本以為我們加上 classificationType: Cesium.ClassificationType.CESIUM_3D_TILE 這個屬性,就萬事ok了,可是沒想到折騰了一天多,才搞定。我們來說說我踩到的坑。先來看看cesium官方對這個屬性的解釋
技術分享圖片
cesium官方文檔對分類屬性的解釋
這段話下面少見的標註了 試驗性提示,大意說這個3dtiles的分類屬性尚未完成可能隨時修改,這個屬性在1.37版本裏都有,到現在快一年了竟然還是這樣子,只有一個可能,需求太少了,幾乎沒人在做這種3dtiles。:(
其中還有很關鍵的指出來,這種3dtiles對gltf有一些限制:
1,必須有position和batchid。
2,相同batchid的索引需要連續存放
3,所有shaders 和 techniques會被忽略。
4,只支持這兩個擴展。
5,gltf只能包含一個node,這個node只能包含又給mesh,這個mesh只能包含一個primitive。
好吧這段話是我碰到默認奇妙問題的時候才看見的,所以這些坑一個不落的全部踩到。總結一下所有的坑:分類3dtiles的gltf必須有如下限制:
1,必須有position和batchid,最好不要有其他比如normals或者textcoord,一個是沒有用,另一個是可能會影響position的偏移值,導致坐標不正確。這個坑真的跟了很久源碼才發現。不設置分類屬性的時候,渲染正常,設置之後也不報錯,就是沒效果,這種最麻煩,折騰了大半天。
2,相同batchid的索引需要連續存放,這個如果不滿足,就會碰到一個訪問array越界的錯誤,依然是跟蹤源碼發現,cesium的解析部分有點問題。
3,所有shaders 和 techniques會被忽略。這條最坑人,恰恰相反,至少目前gltf2.0,如果只用pbr材質,代碼就會崩潰。而必須自定義shader。因為這個,我又對這個工具增加內置的自定義shader功能,增加自定義shader帶來很多代碼,這個又是熬出來的,哎。

4,只支持這兩個擴展,這條倒是真的,至少draco壓縮的擴展是不支持的,所以如果做分類3dtiles,請不需要選頂點壓縮。
5,這條沒什麽,因為之前有人嘗試過,發出了他的錯誤提示,當時我就註意到了這個要求,無非花點時間,把我的多個primitive組織在一起。但是這也變相要求,我們生成分類3dtiles的時候,不能設置側面紋理。
6,還有一個小坑,就是在node裏必須設置transform,如果不設置,就報錯
我們先欣賞一下效果,很完美,精確裁剪,再也沒有以前做的那樣的毛刺了
在線示例:http://www.cesiumlab.com/demo/classify3dtiles.html
技術分享圖片
最終的分類效果
代碼也很簡單
技術分享圖片
分類3dtiles加載代碼
註意 其中的顏色設置,這裏也有點小坑,這個透明度不能設置為0,設置為0,cesium內有性能優化,就不渲染了分類3dtiles,不渲染自己就沒有效果了。所以我們設置了一個極低的透明度。讓他沒交互的時候不影響原來的3dtiles。
我們再來引申幾個問題:
1, 是否只能對傾斜3dtiles做這種單體化?
回答:不是的,只要是3dtiles都可以,所以對於通過cesiumlab場景處理工具,bim處理工具生成的3dtiles都可以做類似的操作,如下圖
技術分享圖片
對於max模型生成的3dtiles依然可以做類似操作
2,既然這種方式可以做分類交互和屬性綁定,和3dtiles中默認的對象交互有什麽區別,我們該怎麽選擇?
回答:分類和交互以及屬性更貼近實際業務。 我們在數據,尤其是做max場景的時候,更多的是考慮的數據的美觀性,所以數據分割不是那麽嚴格,也很少考慮業務需要,導致很多情況下,比如我們想選中第四層,但是max裏第四層可能屬於不同的node,我們就很難做交互了。這種情況下,我們就可以把max場景和屬×××互獨立出來。max場景只做數據展示,這種數據更新的可能性較小,數據長期不變。分類交互使用分類3dtiles去完成,這種分類3dtiles一般原始數據較小,處理也快,適應屬性多變的情況。
當然下述兩種需求不適合分類3dtiles去實現:
a,需要對原始3dtiles進行部分隱藏或者部分透明,上述效果我們也看到了,分類3dtiles是附著在原始3dtiles上去顯示,他的透明度只能影響附著顏色的透明度,並不能影響原始3dtiles對應部分的透明度,也不能去隱藏原始3dtiles的覆蓋部分。(使用scene.invertClassification 可以隱藏或者設置分類3dtiles不能覆蓋到的地方)
b,對於bim數據或者原來建模的時候已經按照構件去組織的數據,不建議使用分類3dtiles。這類數據已經是和具體業務關聯的,而且可以更好的存儲場景屬性,所以沒必要再做分類3dtiles了。
3,分類3dtiles的性能如何,能否實現對城市級的數據分類
回答:這個我沒有具體測試,如果你們有數據,請聯系我一起測試。但是顯而易見的,分類3dtiles依賴的是陰影體算法,他會至少把原始3dtiles多渲染一次,這個必然會降低性能,至於降低多少,只能自己測了。
歡迎大家進入實驗室,一起討論cesium,3dtiles,單體化,等等。
在線示例:http://www.cesiumlab.com/demo/classify3dtiles.html
技術分享圖片

CesiumLab V1.4 分類3dtiles生成(傾斜單體化、樓層房間交互)