觀看次數 10
Gil Damoiseaux 最近分享了他嘗試通過Unity中的表面著色器從Alyx再現瓶裝效果中的液體的結果。在本文中,他分享了使用各種液體進行實驗的技術細節。
介紹
大家好,我叫Gil Damoiseaux,我是比利時那慕爾的HEAJ(Haute Ecole Albert Jacquard)的講師。我主要講授技術美術(Technical Artist, TA),特別是著色器(Shader)開發,使用諸如Substance Designer和Houdini之類的技術美術工具,並提供有關項目的指導。我還與JangaFX一起擔任技術顧問和研發人員,我們目前正在開發Embergen,一款用於遊戲和電影的實時體積流體模擬軟件。最初,我在那慕爾當地大學的碩士學位課程中學習計算機科學,這是通常的數據庫和與操作系統相關的問題。
然後,我在一家名為Appeal的遊戲公司工作,在那裡我們發行了幾款遊戲,包括1999年基於voxel-based的冒險遊戲Outcast。我還在NeuroTV工作了8年,開發了一種用於電視的實時渲染引擎,用於虛擬場景,avatars動畫或品牌展示。我回到AMA工作室進行遊戲開發,在那兒我開發了Fighter Inside,這是Kinect格鬥遊戲,是Xbox One發行遊戲的一部分。除此之外,我已經提供了一些課程,但後來我決定專注於此,並全職擔任視頻遊戲講師。六年前,我開始以自由職業者的身份工作,並與Grand Designer一起創建了一個實時程序行星生成器,我已經工作了4年,一直在增加功能並對其進行改進。一年半以前,我加入JangaFX是因為我們共享工具開發的共同目標,並且與他們合作是很有意義的,因為我是我自己開發類似的產品。
靈感
總的來說,我一直對藝術創作和創作過程著迷,因此當我有空的時候,我和自己的美術同事一起學習了不同的DCC工具,但是一直以來,我一直回到編程領域。因此,自然地隨著技術的發展,我將著色器開發作為我的主要興趣中心。
總的來說,我曾經還是仍然從範例場景中受到啟發,它在許多方面總是極富創造力和令人印象深刻的技術。30年前,我用彙編語言進行編碼時是Archimedes場景(第一台使用ARM處理器的台式計算機)時的一員……最近,與Etienne Jacob或一般而言,生成藝術是巨大的靈感來源。當然,所有遊戲行業也對我產生了啟發,我不禁分析我在屏幕上看到的效果,有時甚至嘗試重現它們。
像我們許多人一樣,我一看到它就對VFX印象深刻,不知道如何做才能看起來那麼自然和真實。然後,我在Twitter和Discord上到處都看到人們在嘗試重現它,並挑戰了也要重現這個效果,這是一個有趣的周末項目。嘗試重現良好效果始終是一個好習慣,並且總是一個機會,可以推動事物發展,學習新技術並了解您可以達到的效果。我(看最後的效果完成先前與其他一些效果,比如在戰神動畫於這裡,解析在這裡),或在蜘蛛俠內部映射在PS4(可在我Github上)。我總是通過這種鍛煉來學習新事物。
瓶裝液體效果的先前工作
前段時間,我在瓶中製作了一種液體效果,但沒有任何物理,卻要簡單得多,只是一個可以更改的水平,但即使這樣也有局限性。這個想法是渲染容器的內部並使液體表面的最高頂點折疊。與用於切割物體的常規alpha測試技術相比,這具有很大的優勢:您可以在適當的照明下獲得液體的實際表面。為此,我只使用了平面投影,該平面投影使用了具有與該噪聲匹配的普通紋理的噪聲紋理。可以在Amplify Shader Editor的社區樣本中找到此著色器。
但是此技術也有很大的限制,您不能在底部設置一個較窄的容器,因為液體會從容器中流出。您可以在下面的示例中看到,我不會降低太多液體來避免問題。
您可以在此處看到原始效果,並使用線框wireframe版本觀看collapsing的效果:
去年,我還在學校舉辦的一個研討會上做了一些著色器,它們使用計算緩衝區存儲每個頂點的值。著色器(在這種情況下為頂點著色器)的主要問題在於它們是無狀態的(stateless),您不能存儲任何內容,只要將一幀中的任何內容都恢復為下一幀即可。因此,例如在單個著色器中進行某些物理操作並不是一件容易的事……除非您在讀寫模式下使用計算緩衝區。這將使您可以存儲和調用每個頂點所需的盡可能多的數據。由於Z預通過或陰影或其他任何原因,每幀也可能會多次調用著色器,因此我不得不在計算緩衝區上實現雙緩衝:一個處於讀取模式,另一個處於寫入模式。
這是在工作坊中進行的著色器,在每個頂點上都有一個簡單的擺動效果,法線指向下方:
因此,最初的想法是將之前的兩個實驗混合成一個新的。液體表面基本上像彈簧網絡一樣起反應。為了更好地控制它,我決定使用沿一個軸(上下軸)移動的彈簧,因為這是液體最明顯的運動,並且還可以防止液體的表面不受控制。容器。儘管它不是真正的液體模擬,但它取代了我以前使用的噪聲紋理並增加了物理特性。我還期望我可以得到一些體面的東西,而不必在表面上傳播彈簧運動,而只是保持運動的局部性……的確如此。因此,在平移或旋轉對象時,我將根據其相對於網格樞軸的位置簡單地向上或向下平移彈簧的位置:如果將對象向右移動,則會模擬左側的頂點,並降低左側的頂點,以模擬液體在相反方向上的積累。之後,彈簧物理學將開始,它將嘗試回到其靜止位置。彈簧離其靜止位置越遠,將其恢復原位的力就越大。除此之外,當前速度每幀都會衰減,以免彈簧永不靜止。那是表面物理學的第一個實現,導致以下結果:
到目前為止,我將存儲在計算緩衝區中:1)頂點的先前位置,從中可以獲取頂點的局部速度(平移和旋轉);2)彈簧在液體表面上方或下方的位置;3)彈簧的速度以及它是向上還是向下移動。
仍然存在一些問題,第一個問題是我受到容器形式的限制,如前所述,容器不能阻止液體溢出,因此是球形容器做的第一個測試。但是,我通過將頂點向容器內部投影而不是簡單地在平面上投影來部分解決了該問題。這不是一個完美的解決方案,但是如果您明智地選擇容器的形狀,則將看不到它的問題。
另一個重要的問題是,那時我無法在液體表面上具有適當的法線,而僅使用法線指向上方,因此缺乏良好的鏡面反射性。
當我仍試圖將所有這些都保存在一個著色器中時,我遇到了一個問題,即頂點不知道幾何圖形,也不知道它們的鄰居。除非您向他們提供信息,否則這是事實:您可以在頂點、法線、切線或貼圖坐標中存儲大量靜態信息。因此,我編寫了一個小腳本,通過在未使用的紋理坐標通道中存儲其兩個鄰居的索引來改善網格。由於頂點的位置也存儲在計算緩衝區中,因此任何頂點現在都可以獲取兩個鄰居的位置,因此可以重新計算其法線。實際上,這是上一幀的正常現象,但這是無法確定的。
為了改善液體表面的形狀和運動,我根據頂點的世界位置用一些正弦曲線調製了注入的力。這立即增加了許多細節,並創造了更加可信的液體表面。當時,我還增加了網格密度以獲取更多詳細信息。
之後,添加了通常的屏幕空間折射,以得到一些半透明液體。在折射過程中,我還多次採樣,以使半透明性變得有些粗糙,並避免使用純半透明的液體。您可以在此處看到常規折射和多次採樣。請注意,玻璃也將這種技術用於磨砂玻璃帶。
泡泡和泡沫
在發布第一版液體後,我從Twitter社區獲得了很棒的反饋,但是我經常收到的評論是“您何時添加氣泡?”。
為了產生氣泡和泡沫,我需要跟踪液體的攪動程度。最簡單的方法是添加一個存儲在計算緩衝區中的變量,該變量將通過在每個幀中添加前面提到的脈衝的絕對值來累積本地施加的所有外力。此變量還減少了每個幀,以允許我模擬泡沫和氣泡的消散,並將其用作遮罩。
對於氣泡的渲染部分,我計算了一個3D噪聲,該噪聲向上滾動並且根據遮罩使用一些平滑階段來使氣泡變大或變小。對於泡沫,在液體表面上使用遮罩可在其頂部添加一些額外的位移,並且還可以對表面進行不同的著色並修改局部半透明性。
這是氣泡和泡沫的第一個版本:
由於最初的效果已經使較大的氣泡產生了令人信服的效果,因此我必須改善自己的性能,尤其是在來自比利時的啤酒之鄉。我在Fusion 360中為啤酒瓶建模,並找到了不錯的假品牌紋理以正確完成它。
這次,我在頂點著色器上使用了另一種3D噪聲來隨機化泡沫的消散,而泡沫的消散最初太過人工了。
使用粘性液體
我想要更多這些,因此在探究可能性之後,我想到了更稠和更粘稠的液體,例如糖漿或血液。我禁用了泡沫,並且為了跟踪容器內部的粘性部分,我添加了另一個變量,以保持液體的局部粘性。僅當頂點在液體表面以下時,此值才設置為最大值,並且在表面上方時緩慢且隨機地(使用與以前相同的3D噪聲)逐漸消失。
但是渲染必須做兩次以上,因為液體的頂點已經用於顯示表面。因此,為此,我必須做五遍:容器的後玻璃杯,液體的粘性部分的背面,液體本身,粘性液體的前部分以及容器的前玻璃。粘滯傳遞非常輕巧,僅讀取頂點著色器上的遮罩值,但無論如何仍需要2次附加傳遞。
這是該技術的早期版本:
著色器非常靈活,並具有一些參數,例如彈簧的強度:值越高,曲面恢復原位的速度就越快。另一個有用的參數是彈簧的阻尼,它定義了前一幀的速度仍將保留:阻尼越高,液體感覺越濃,因為移動速度會更長,因為幀之間主要失去了速度。
這是一種更稠密和粘稠的液體:
對於前面提到的投影校正,液體太粘可能是一個問題,因為您更有可能使液體從容器流出。
理論:一瓶香檳
如果要製造一瓶香檳酒,主要問題是液體再次從容器中流出,或者您必須將瓶子蓋得盡可能低。這就是我對啤酒瓶所做的事情,使用瓶頸上的標籤將其隱藏起來。
將液體倒出瓶子會引發更多的問題:第一個問題是將瓶子的容量降低一半以下將重點放在假的液體物理學上,第二個問題是您需要更好的物理學來處理倒酒,至少像粒子一樣,或者最多像是適當的液體模擬一樣。瑞安·布魯克斯(Ryan Brucks)最近在這個方向上做了一些非常酷的實驗,但是他的方法與我的方法完全不同。因此,這將是一個更具挑戰性的設置,我可能會朝著不同於此技術的方向去做。
理論:變色液體
如果要在搖動液體時改變其顏色,可以使用上述攪拌變量來實現。攪動得越多,可見的二次色就越多。在下面的測試中可以看到它正在工作,但是有點粗糙。
正確混合多種顏色可能最多暗示某種顏色擴散,甚至暗示某些低清晰度實時流體模擬。
不過,在大多數情況下,簡單的解決方案可能就足夠了,就像在著色器開發中一樣,使它看起來複雜並且在大多數情況下保持簡單和快速是更可取的。
後記
這種影響的挑戰主要取決於使用情況和最終平台。就我而言,我對自己的工作沒有任何限制,我只是希望它看起來令人信服和酷。如果您接受隨之而來的限制,那麼該技術當然可以在項目中使用。為了讓您大致了解一下,當前的實現以及所有花俏效果的時間,使用50K三角面模型,在我的2080RTX Ti上花費了大約1.5ms。這個實驗並不意味著可以投入生產,因此我沒有花費很多時間進行優化,但是還有很多可以改進的地方。
我已經對其進行了改進,以查看該特定技術是否可以使人信服,並且我還想嘗試許多其他技術以使其更便宜或更嚴格。對於給定技術,總是有改進的空間,新思想,新用法。總會有一些有創造力的人來執行外觀更好或更快速的實現,這就是驅使我嘗試新事物並繼續在任何地方尋找靈感的原因。一旦您沉迷於創意編程或任何其他領域,您將永遠不會停止尋求更多的東西,並學習和嘗試新事物以打開新的大門。
https://80.lv/articles/simulating-liquids-in-a-bottle-with-a-shader