引子
中間有事,耽擱了好久才更新。這一篇要做的是視頻投影,也有視頻投射、視頻融合之類的叫法。本篇內容比較簡單,僅停留在出效果的層面,所以想要高級應用的小盆友可別扔我雞蛋啊,待我日后好好研究一番再來補上。要知道,要做到視頻與模型真正的融合可不是一件簡單的事情,不誇張地說,申請個專利都是沒問題的。現在嘛,入門級實現,先講究看着吧。
預期效果
實現原理
開篇就說了,咱們這篇是入門級的,所以原理非常簡單,用一句話來描述,就是給一個Geometry附上材質,然后貼到地圖上。涉及到的API內容也比較少,Material、RectangleGraphics或PolygonGraphics,前幾篇也介紹過類似的接口了,就不在贅述了,可以點擊鏈接查看官網API。
具體實現
Video標簽
要把大象放冰箱,第一步你得有大象啊。先插入一個視頻標簽,里面是你的視頻地址,這里我借用一下官網示例里的地址了。
1 <video id="myVideo" muted="" autoplay="" loop="" crossorigin="" controls=""> 2 <source src="https://sandcastle.cesium.com/SampleData/videos/big-buck-bunny_trailer.webm" type="video/webm"> 3 <source src="https://sandcastle.cesium.com/SampleData/videos/big-buck-bunny_trailer.mp4" type="video/mp4"> 4 <source src="https://sandcastle.cesium.com/SampleData/videos/big-buck-bunny_trailer.mov" type="video/quicktime"> 5 </video>
我們看到沙箱中給了我們三個地址,分別是三種格式,這里我們推薦使用webm格式,一看這名字就知道它對web支持最好了,實際測試的過程中,其他格式如mp4會有卡頓或延遲的情況出現。
實體容器
大象有了,現在就差個冰箱了。通常情況下我們會使用Rectangle,因為視頻的形狀就是四四方方的嘛。
1 // 獲取視頻元素 2 const videoElement = document.getElementById("myVideo"); 3 // 創建實體對象 4 const rectangle = viewer.entities.add({ 5 rectangle: { 6 coordinates: Cesium.Rectangle.fromDegrees(-80.0, 39.0, -79.0, 40.0), 7 material: videoElement 8 }, 9 // 或創建多邊形 10 // polygon: { 11 // hierarchy: new PolygonHierarchy(positions), 12 // material: videoElement 13 // }, 14 }); 15 // 鎖定實體對象(這句可有可無) 16 viewer.trackedEntity = rectangle;
好了,大功告成了。Waht? 這就好了?是的,這樣就已經把視頻投影到場景中了。哈哈,水了水了,這篇文章真的水,再多寫點有的沒的吧。
時鍾同步
雖然功能已經,但是不要忘了頁面中還掛着那個video呢,那么干掉它吧,設置樣式隱藏誰都會。注意,只能是隱藏,不能刪掉哦,刪掉的話那你場景中的視頻就是無源之水了。
1 videoElement.style.display = 'none';
OK,煩人的畫面不見了,咦,你會驚喜的發現,場景中的視頻怎么不播放了。懷疑是video標簽隱藏的關系,把它再顯示出來,果然視頻又動了。怎么辦?這時候就要用到時鍾同步了。這里使用的是VideoSynchronizer,它可以使視頻元素與Cesium的模擬時鍾同步,下面看下它的構造函數:
名稱 | 類型 | 描述 | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options |
Object | 選項子屬性:
|
1 let synchronizer = new Cesium.VideoSynchronizer({ 2 clock : viewer.clock, 3 element : videoElement 4 });
加上這一步之后,再運行代碼試試。矮~矮~怎么視頻還是不動呢,不光如此,就連video標簽里的視頻也不動了。小盆友,別急,不動就對了。原來啊,視頻已經和模擬時鍾同步了,也就是說時鍾動了你視頻才能動啊。哦~恍然大悟,我去打開時鍾。
1 viewer.clock.shouldAnimate = true;
現在再把video便簽隱藏了就完全沒有影響了。
小結
沒有做多深入的研究,注定是就是一篇水文,群里有有伙伴問我怎么調整視頻的形狀,我說很簡單啊,只要改變實體的形狀就可以了,結果啪啪打臉,如圖:
我們看到,改變實體的形狀並不能影響到視頻投影,默認的是按最大邊填充的,多余的都被截掉了。我們知道,實際的監控視頻正射的很少,要想貼合三維模型肯定要做梯形校正的,這是個很實在的問題,后面必須解決掉。現在初步的思路是有的,既然視頻投影就是材質填充,那么在着色器中通過紋理坐標應該能控制紋理的形狀。哦嚯,又立了一個flag,之前的可視域分析還有坑沒填,哎,時間真心不夠啊。
最后,照例來一波宣傳:如果你有什么好的想法,可以給我留言,或者可以加這個群854943530,群的宗旨不追求人多,只追求切實解決問題,真正學到東西。
后記
后來,萬能群友給了個思路,又重新弄了下,大致是參考了可視域分析的效果,還別說,現在真有點投影儀投射影像的感覺了,陰影部分是不會貼圖的,而且垂直邊緣不會出現斷崖式的銜接,看起來很舒服,來看看效果: