繪光:冰暈模擬的故事

繪光:冰暈模擬的故事

來自專欄光怪陸離224 人贊了文章

一、緣起

7 月份這一期的《中國國家地理》有好友計雲老師主筆的一篇文章《冰暈,世所罕見,中國最美》,介紹了國內冰暈愛好者這一群體。文章中我貢獻了一些計算機模擬結果。趁著雜誌剛剛出來,我也寫幾句我這部分的工作。

《中國國家地理》2018 年 7 月號

冰暈嘛,指的是大氣中雲層里冰晶引起的光學現象,大家偶爾能見到太陽周圍有一些弧啊、暈圈啊、光斑啊什麼的,這就是冰暈了。這冰暈看似平淡無奇,大部分人從小到大記憶中也都有見過過一兩回。可是細細研究起來,中間還大有奧妙。冰暈的不同形態,反映了雲層中冰晶的形狀、排列方向等信息,除了賞心悅目之外,也可以為大氣研究提供寶貴的資料。古語有云「日暈而風,月暈而雨」,就是古人對冰暈現象與天氣變化之間關聯的樸素認識了。

要說起我跟冰暈的緣由,還得說到今年 2 月份,我被好友計雲拉入了一個天象討論群,大家在討論冰暈。這可是我感興趣的話題,群里好多大師們都是這個領域的達人,一來二去,大家也漸漸熟了。

在交流過程中計雲老師提到,計算機模擬模擬在研究冰暈過程中非常重要。很多罕見的冰暈形態都是在計算機模擬中先被發現,而後才有自然界中的照片佐證;也有一些自然界中拍到複雜的冰暈,在計算機模擬的幫助下才揭開身世之謎。目前我國廣大冰暈愛好者(甚至學術研究者)研究冰暈的一個困難是缺少有效的模擬模擬的手段,國外的通用軟體並不向我們開放。有時候拍攝到了一些罕見的冰暈形態照片,卻難以通過模擬分析來敲定成因,頗為遺憾。

二、他山之石可以攻玉

聽計雲說著模擬軟體的遺憾,我不禁心裡有點躍躍欲試:這不是把光學和編程結合一下嘛!涉及到的知識並不高深,沒有超出幾何光學範疇,這正是我擅長的話題。

萬事俱備只缺一個程序員——巧了,我自己就是程序員。

說干就干。這個程序核心部分在光線追蹤,一條光線射入一個特定形狀的冰晶,在每一個表面都有折射和反射,這些折射反射之後光線會繼續傳播,碰到下一個表面的時候又會發生折射和反射……如此反覆迭代。

儘管是叫做光線追蹤,但是和計算機圖形學(Computer graphics)中的光線追蹤(Ray tracing)演算法並不完全一樣。圖形學中的光線追蹤演算法是從屏幕空間出發追蹤光線,並且大部分場景下物體表面對光線的作用是有一定隨機性的;而冰暈形成過程中所有光線交互過程都是確定性的,滿足幾何光學的折射和反射定律,所以從光源出發進行遞歸地光線追蹤效率更高。

計算機圖形學中的光線追蹤,從屏幕空間出發開始追蹤光線

追蹤冰晶中所有折射和反射的光線

儘管與計算機圖形學領域裡光線追蹤演算法不完全一樣,但處理光線與物體表面交互的過程是非常類似的,無論是遞歸的光線追蹤過程,還是光線與表面之間的幾何計算,我對此非常熟悉了。花了兩個下午的時間,很快寫出一個 matlab 的原型演算法來。

這裡還有一個小花絮,我在收集模擬程序該有哪些功能過程中,專門查閱了目前國外通用的模擬程序 HaloPoint 的說明書。作者在說明書里提到,他最開始也是想基於 matlab 開發軟體的,但 matlab 太慢了,最後還是用 C++ 來寫。

可是按照我的經驗判斷,這個程序的瓶頸在光線追蹤的過程,而光線追蹤過程涉及大量的矩陣和向量運算,在 matlab 中是做了非常多優化的。我認為這個程序用 matlab 來寫,只要設計合理,並充分進行向量化操作,速度並不會慢得難以接受。事實證明了我的判斷,我寫的 matlab 原型演算法,運行速度只略慢於 HaloPoint 說明書中描述的典型速度。

三、路漫漫其修遠兮

這個 matlab 程序解決了有無的問題,是從 0 到 1 的一步跨越,很多簡單場景下可以直接用這個程序進行模擬驗證了。我們幾個好友在接下來的一段時間,就用這個簡陋的程序,模擬驗證了很多冰暈的場景,也在實踐中慢慢打磨演算法,修復錯誤。

然而我在使用過程中也意識到,與 HaloPoint 相比,我的程序差距還是很大的。我的程序只能模擬六稜柱形狀的冰晶,而自然界中還存在大量偏六稜柱、六稜錐、三稜錐/柱等奇形怪狀的冰晶;而且我的程序也只能模擬單色波長的光線,難以反映出冰暈的真實色彩;再加上深度使用後我也意識到,既然這個 matlab 原型程序就有與 HaloPoint 相匹敵的運行速度,說明 HaloPoint 並沒有充分利用現代計算機 CPU 的性能,我還能做得更好。

為此,我開始用 C++ 來重寫整個程序。

冰晶形狀太單一?我就根據我們實際使用中需要的冰晶形狀,一個一個寫對應的冰晶模型。甚至還考慮到,在極端情況下對異形冰晶模擬模擬的需求,寫了一個簡單的 OBJ 文件解析器,可以在 3D 建模軟體中建立任意形狀的冰晶,導出 OBJ 文件,進而在程序里進行模擬模擬。這就完全擺脫了冰晶形狀的限制。在後來的一次罕見冰暈的模擬過程中,這個功能真的派上了用場(《中國國家地理》上的文章中有提到),這已經完全超越 HaloPoint 的水平。

無法模擬真實色彩?正好用上我以前的研究,根據光譜直接渲染 RGB 色彩(參見本專欄之前的文章 光譜渲染的幾個例子),得到色彩鮮明生動的模擬結果。與 HaloPoint 相比,也不遑多讓,甚至色彩表現更優秀。

速度還能不能更快?當然可以,用 C++ 重寫之後,可以從更多方面進行優化。我精簡了計算過程,減少了無謂的內存拷貝;我自己實現了一個簡單的內存池,避免了大量光線對象的申請銷毀的開銷;我自己實現了一個簡單的線程池,更充分利用現代計算機多核 CPU 的優勢;在矩陣計算中適當使用了指令集優化,更充分挖掘了計算機 CPU 的計算能力。在充分優化後,程序運行速度已經超過 HaloPoint 上百倍了。

更靈活的功能?在重寫的過程中,我對核心演算法,遞歸追蹤光線的部分進行了重構,充分考慮需求的多樣性。所以當計雲和我商量增加多晶模擬的時候,我毫不費力地改進了程序對多晶情況進行了支持。這更是超過 HaloPoint 的新特性,HaloPoint 由於設計問題,很難對多晶情況進行模擬,即使採用非常繞的方式來勉強模擬少數場景,速度也變得非常慢。在多晶的場景下,我的程序運行速度更是 HaloPoint 的數百倍。

我的程序對某次大規模冰暈現象的全天空模擬結果,詳情參見《中國國家地理》的文章

接下來呢?我打算把這個程序放到雲端,同時做一個網頁版的用戶界面,開放出來給所有冰暈愛好者們使用,現在正在搭建伺服器框架,預計不久之後大家就可以用上了。

四、長風破浪會有時,直掛雲帆濟滄海

中國地大物博,地形氣候複雜多樣,這對冰暈的研究其實是非常有利的條件。歐美專家總結的一些罕見冰暈現象,在中國卻往往是每年都能見到。國內對冰暈的研究起步晚,到現在為止還沒有中國人發現的新的冰暈現象。若論天時地利,我們是有優勢的。只是差了人和,缺少一點點運氣。計雲老師就曾經拍到過一張疑似新種類冰暈的照片,終究還是雜訊較大,可信度過低,而沒有被確認。

計雲老師拍攝到疑似新種類冰暈的計算機模擬模擬結果,注意畫面中下部偏左側暈圈上有一處變寬凸起,可能是一種新種類的暈,詳見《中國國家地理》的文章

在《中國國家地理》的文章中,計雲老師無不激動地表示,隨著越來越多的人對冰暈現象感興趣,加入到隨手記錄的行列中來,我們一定能發現新的冰暈種類的。屆時,從發現到驗證,都將是完完全全的「國產貨」。

PS,模擬程序已經開源,歡迎交流:

LoveDaisy/ice_halo_sim?

github.com圖標
推薦閱讀:

Stampack板料成形模擬分析軟體
異響性能前期設計預防︱CAE模擬過程中全局阻尼的定義(Ⅱ)
金屬裂紋擴展與損傷容限分析
【技術】FLUENT模擬氣泡的破碎與凝聚

TAG:模擬模擬 | 光學 | 計算機圖形學 |