​TGDC | 向陽而生 —— 光線追蹤的專案應用

謝淵發表於2020-12-16
2020年12月8日,由騰訊遊戲學院舉辦的第四屆騰訊遊戲開發者大會(Tencent Game Developers Conference,簡稱TGDC)進入了第二天的議程。來自騰訊NExT Studios工作室的高階技術美術師謝淵分享了NExT工作室在光線追蹤技術探索與運用上的思路。以下是文字實錄:

大家好,我是來自於NExT工作室的謝淵,今天有機會跟大家一起聊一聊光線追蹤。

真實世界的成像

首先在我們瞭解光線追蹤之前,我們看看真實的世界它的光照是如何進行的。

我們現在看到的這張圖,通常我相信大家應該不會用人眼直接去看太陽吧?或者去看一些光源。大多數的時候,光照直接從窗戶、門直射進來,進來之後經過牆壁或者物體,進行一些二次反彈、三次反彈,逐漸隨著光的能量的衰減,我們大多數時候看到的是這樣一副影像。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

從微觀的角度,我們看一看光線是如何運作的。假設一束光打到一個平面上,這時候的平面,在自然界的視角里,當我們把它無限放大以後會發現,它的表面並不是那麼的完美,那麼平整,所以說它的表面上會有很多小的起伏,我們稱之為微表面。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

光線打到這個微表面上面以後,又會隨著這個凹凸不平反射到不同的方向。在用電腦進行模擬自然界光線的時候,比如說我們現在看到的上方這個圖。

這是一個很簡單的場景,一個很小的屋子裡面,上面有一盞燈。那麼這盞燈它的光源發散的方向是四面八方的,我們可以想象出每一束光線打到周圍的牆壁上之後,又隨著牆表面凹凸不平,又發散出更多的一些二次反彈,那二次反彈之後又打到一些桌子上、地面上、房頂上,每接觸到一個平面,又進行了一些更多次的反彈。

可以想象,這樣的一個運算量,其實是非常巨大的。所以通常我們在模擬這樣的一個光照情況下的時候,之前都通過一個離線渲染的方式來呈現出來的。

光柵化渲染

​TGDC | 向陽而生 —— 光線追蹤的專案應用

現在我們再想想,如果我們再實時渲染領域,那麼如何去呈現這樣的一個自然情況呢?這時候我們要引入一個概念——光柵化。

什麼是光柵化?當我們眼睛看到一個螢幕之後,我們所關注的所有的內容是在這個螢幕內的這些物體,所以這個時候,我們會以螢幕空間做一個裁切。

也就是螢幕外的東西,我們暫時先不考慮到它的一些計算,然後,我們把螢幕上的這些三維物體的資訊投射到螢幕的每一個網路畫素上。同時在整個三位場景裡面,把轉換到螢幕上的這些資訊進行分類。比如說有一些法線資訊、有一些深度資訊、有一些ID資訊,諸如此類等等。

然後最後當我們渲染的時候,我們會呼叫這些儲存到視訊記憶體裡面的不同資訊,進行一個合成運算,那這樣最後就是我們看到的,最終的一個畫面效果。

通過剛才的一個簡單的描述,我想大家應該可以理解到,這種方式它最大的優勢是在於快,非常快。因為它會刨去掉很多看不見的一些資訊,比如螢幕外的資訊統統不算;第二個呢,它會把很多三維資訊轉換成以螢幕畫素的形式作為計算,那這樣就大大節省了很多運算量。

不過從另一個角度去看,這樣的方式它已經大大地削弱了一些資訊。所以很多基於物理上面的一些渲染,或者說一些很好的效果,比如說螢幕外的一些反射等等,在光柵化的渲染下面,並不能很好地呈現。

光線追蹤細節的表現

​TGDC | 向陽而生 —— 光線追蹤的專案應用

現在我們可以看一下《重生邊緣》這個專案。我們可以看到光線追蹤開與關的區別。那麼右上角大家看到這個綠色LOGO,RTX ON的時候代表光線追蹤此時已經被開啟了,RTX OFF則代表光線追蹤此時已經被關閉。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

目前我們可以看到此時此刻RTX,就是光追已經關掉了。那麼在RT關掉的時候,它地面這個水潭上面的反射的資訊大家可以看到,由於受到螢幕空間的限制,它反射的資訊量非常少,螢幕外很多的資訊並不能正確地反映過來。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

當我們在RTX ON的時候,就反射到很多螢幕外的一些資訊。這塊大家看到的是一個鐵絲網的一個投影,在光追下面的一個投影的效果,這個投影它來自於我們鐵絲網是採用Alpha test貼圖進行製作的,所以說在光追開的時候,隨著光源與被投射物體的距離的近和遠,它有一個半影的效果。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

當我們在光追關掉的時候,會發現此時的這個投影是清晰的,但是這樣對於我們在自然界觀察的物體來講的話,其實並不是很正確。因為隨著物體投影距離的長和短,它的影子會有一個逐漸擴散的一個半影效果,這就是非RT情況下面看起來不真實的一個表現。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

這裡也是一個水潭,它也是在一個陰影下面的。我們通過水潭裡面的反射,也會看到天空上面的一些資訊,哪怕這個天空它並不在我們螢幕內顯示。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

反之,關掉以後是烏黑一片,所以說這就是光線追蹤帶來的一個視覺上比較大的一些差異性。

通常我們在設計一些光線追蹤場景的時候,也會考慮到有一些比如說夜晚,或者一些反射金屬物體比較多的這張情況,因為這也是比較容易去展現光線追蹤的。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

這是角色在一個動態燈的一個投影情況下面的陰影效果,此時RT是關著的,所以你會發現它的影子就是從近處到遠處一直都是比較實的、比較銳利的。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

反之,但RT開了以後,它有一個半影的效果,動態物體的這麼一個半影效果,是非常明顯的。大家可以考量一下自己平時在路燈下走路的時候,你發現自己的影子是怎麼樣的效果。

所以整個場景裡我們儘可能用了一些動態燈,然後動態物體,然後反射,更多地去營造光線追蹤,呈現出來的一些特有的效果。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

光線追蹤渲染

通過剛才那個視訊,我們看到了RT在實際遊戲專案中的一些呈現。那這個時候,我們就要回到我們一開始的話題,就是到底光線追蹤是如何去渲染的。

在一開篇的時候,我提到了我們自然界的光線都是從光源出發,對所遇到的物體進行一次二次的這樣的反彈。那麼光追恰恰相反,它是從我們的攝像機作為一個射線投射出來,當這個攝像機如果在我們的三維場景裡面,求交了某一個物體的一個面,那麼相應它也會發生這樣的一些反彈。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

經歷多次的反彈以後,可以追溯到這個物體、乃至光源,然後依次把這樣的資訊再反彈到我們的眼睛當中,那樣就是形成了整個光線追蹤的一個路徑的迴圈。可以知道光線追蹤它是有反彈的這麼一個概念在裡面的,所以大家看看現在右邊的這張圖。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

當我們把反彈的次數逐次提高以後,我們會發現每增加一次,它反彈的次數和數量都得到了巨大的提升和變化。所以說在實時渲染領域,儘管我們已經做了從螢幕出發的光追渲染方式,但是它的計算量依舊是比較巨大的。

這也就是為什麼光線追蹤在實時渲染領域遲遲不能落地,遲遲不能在真正的專案中進行大批量推廣的一個原因。

GPU提升帶來了技術革新

​TGDC | 向陽而生 —— 光線追蹤的專案應用

現在我們可以看看這張圖,這個是近30年來CPU和GPU整個發展的路徑。下方這個藍色的線是CPU效能的一個提升,上方綠色的是顯示卡GPU的一個提升,通過這張圖我們很明顯地看到我們GPU發展的速度遠遠超過了CPU提升的這個幅度。

特別是在2018年的時候,微軟釋出了DXR,一個基於Directx的RT的這麼一個API結構,同年Nvidia也推出了RTX顯示卡,我們之前的顯示卡一直是GTX,2018年的時候終於出現了RTX顯示卡。

那這個顯示卡它和以往的顯示卡有什麼區別呢?它採用了一個基於光線追蹤硬體加速的這麼一個核心,所以說從RTX顯示卡開始,我們可以真正地把光線追蹤應用到實時渲染領域。

自從光線追蹤在實時渲染領域應用以後,我們就可以在它上面應用一些原來基於一些離線渲染,物理的一些折射、反射、焦散的效果。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

在我們實際的專案當中,就是光線追蹤它通常是由四種形式得以呈現的,一個就是光追的AO,包括它的陰影,包括它的反射,以及它的Global Illumination,就是GI。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

光線追蹤的優勢

我們逐個瞭解一下,光追在遊戲當中究竟能給我們帶來些什麼。

這是一張截自於一個遊戲畫面的截圖,我們可以關注一下綠色箭頭所指的方向,這都是一個水潭和一個鏡子,我們想看一下但我們光追開了以後的變化。

大家可以比較容易地去發現,當它左側的黃色欄杆在非RT的情況下並沒有比較準確、完整地把它渲染出來,包括下方的水潭,其實它的上方有一個黃色的廣告牌,但是在螢幕空間反射的時候,因為沒有看得到這個廣告牌,所以說也就沒有辦法正確地反射出它在水面的倒影。

​TGDC | 向陽而生 —— 光線追蹤的專案應用
[ 光追沒開之前 ]

​TGDC | 向陽而生 —— 光線追蹤的專案應用
[ 光追開了以後 ]

相對RT這塊,就是可以呈現出很多的細節,包括一些準確的位置。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

這也是我們通常在遊戲開發裡面會遇到的一個情景,就是我們會在螢幕空間反射之外,有的時候我們會加一個反射球Reflection Capture,那這個東西,就中間那個白色的球,它主要的目的就是以它所在的位置中心,在它的這個半徑範圍內會抓取一些當前三維場景的一些資訊,並烘焙到一個圖上面。

通過這種形式,去彌補一些螢幕空間反射所不能呈現出來的一些資訊,但是它的劣勢也顯而易見。

第一,由於本身它計算的精度問題,它並不能非常準確地呈現出一個反射的位置;第二本身這張圖它的尺寸由於也是受限,為了儘可能地去減少視訊記憶體的一個開銷,所以說它的反射出來的內容也是比較模糊的。

同時,當我們在一個遊戲場景中大批量採用這樣的技術的時候,對顯示卡的視訊記憶體效能開銷也是比較巨大的。而我們如果在這樣的一個開闊場景中,我們採用了一個RT的反射,這樣的話,我們看到的內容無論是準確性,包括清晰度都大大的改變,而且也會減少一些視訊記憶體的開銷。

下面這張圖是一個動態物體的反射展示。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

我們知道動態角色在遊戲中他們的一些反射,之前提到Reflection Capture是沒有辦法的,因為它只能抓取一些靜態的物體,所以說在動態物體的時候,只能是一些螢幕空間的反射來支援它的一些比如像現在水面上的一些效果。

那麼我們看一下RT開了以後,在動態物體移動的時候,它的投影反射依然是比較清晰可見的。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

下面這張圖,我們可以看一下,當整個海量AI的這麼一個場景呈現在我們視覺當中的時候,角色身上這些材質的Roughness它是相同的,那這樣的話我們可以進行一個渲染的合批,在這麼多角色被RT的反射渲染下,我們依然可以達到50幀。

所以說這一塊優化效能也是很有幫助,與我們在整個大場景的一些渲染。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

下面這張圖大家不知道有沒有發現什麼問題,這是一個在螢幕空間AO的一個效果,當我們的視角由俯視變視到平視的時候,它的這個柱子的AO會發生一個很奇怪的現象。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

那麼為什麼會產生這樣的效果,我們來分析一下。

當我們比較俯視的時候,會發現柱子邊上的這個AO它的螢幕空間產生的AO的原理其實基於一個螢幕深度圖的快取計算,也就是說它會比對當前物體前後的畫素,誰深度更深一點,當兩者的深度差值如果小於AO的取樣半徑的時候,那就會被認為前方物體對後方物體產生了一個環境的閉塞,產生了AO。

那麼正因為我們是俯視的角度,所以說這樣的話,它的深度的差值的對比也是比較小的,那這樣電腦就會誤認為是這個杯子離這個地面比較近,從而產生了這麼一個錯誤的效果。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

如果我們把它的視角稍微平視一點,這樣你就會發現它的這個出錯的現象會稍微好一些。這其實也是因為當這個角度看上去,它的深度的差異性會比較大,當它超出了我們的這個取樣半徑以後,相對來講這樣的一個被誤認為遮擋的AO關係就隨之而減少。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

​TGDC | 向陽而生 —— 光線追蹤的專案應用

這個就一目瞭然了,這就是光線追蹤的AO,它基於物理運算,你會發現它呈現的AO的效果是非常正常的。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

下面我們來聊一聊光線追蹤的陰影。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

現在在光線追蹤被關掉的情況下面,角色它的投影來自於一盞光,這盞光我們採用的是CSM的一個投影,我們把contact shadow其實已經開了,但儘管如此我們會發現在他的衣領上,包括他的衣服上面,依然就會沒有明暗關係,顯得這個衣服是浮在人身上的,包括眼鏡周圍都沒有一些立體的這張感覺。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

這是一個光追開了以後的效果,首先他的這個衣服和身上的內衣之間的半影效果非常真實,包括他的頸部的衣服,儘管它的厚度很薄,但我們依然很清晰地會看到它的一些投影,投在頸椎上面,包括整個眼鏡這一塊兒,都顯得非常自然,接近於我們真實的效果。

這就是基於光追的一個陰影所呈現出來的投影和傳統投影之間的一個區別。

這塊我們介紹一下光追的一個GI。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

目前就是一個簡單的小房子,裡面放了一個綠色的球,目前這個效果就是我們沒有開RT,那整個場景裡面它只有兩盞光,一個是sky light的天光,包括一個directional light的直射光。

通過這張圖,我們可以看到整個室內的效果是很平的,因為它的漫反射並不能很好地被遮蔽,所以這樣看起來的這個場景就會顯得比較缺乏體積感,會比較平一些。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

這是開啟的一個RTGI的效果,和剛才這張圖大家可以看一下,我覺得是天壤之別。所以有GI和沒GI差了很多,那麼GI這張圖我們可以切換到燈光模式下去看一看。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

首先,它在室內會產生一個漫反射的遮蔽,那提及感瞬間就出來了。然後同時我們中間這個球之前是有綠色的,光追經過它的一次反彈、二次反彈之後,它會把球上面的一些顏色帶到周圍的一些牆壁或者地面,甚至天花板上面。

那右下角的那個引數大家可以看一下,我們現在使用的這個Bounce也就是它的反彈,其實是兩次,兩次已經可以達到這樣的效果了。

這塊我要說一下,我們在實際專案中並沒有採用RTGI。

第一個原因就是我們整個開發的團隊自己本身有一個動態的GI的系統;第二個就是動態GI開起來以後,最大我們需要面對的問題還是一個效能問題,如果我們的效能不能滿足,那麼我們可能會降低它的質量,但降低質量後,它的RT的GI會有一些噪點產生,這也就是為什麼我們暫時沒有在專案當中直接使用RTGI的這麼一個原因。

光線追蹤優化

​TGDC | 向陽而生 —— 光線追蹤的專案應用

其實我個人也覺得也是比較關鍵的一塊,就是關於光線追蹤的優化。因為如果光追再好,但是不能把它優化到我們需要的一個效能標準,其實在真正的遊戲專案裡面也沒有辦法去推廣的。

這個場景我們可以看到,在它的左側有一面鏡子,它的右邊有一個純金屬的管子。現在我們在這個場景裡切換一下它的視角,這塊兒大家可以看到,我們是通過這個鏡子來去看它對面的這個純金屬的管子。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

這時候我們發現一個很奇怪的現象,就是管子變黑了。這是為什麼呢?因為大家可以想象我們通過鏡子裡面看到這個管子,能看到管子首先這已經是光線反彈的一次,那麼這也就是我們下方看到的,所敲的一個反彈次數的命令,當前幀數也是在將近於60幀的這麼一個狀態。

但是如果我們希望鏡子裡面的這個金屬體它上面依然有反射效果,這就得二次了,這也就是為什麼你現在看到的是一個黑管子,現在我們把它提到二次。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

現在金屬管子上面的一些細節,周圍的一些物體,也就能被準確地呈現出來,但是很不幸的是,我們會發現它的幀數已經瞬間掉到了19幀左右。我們接著繼續增大它的反彈的次數到三次。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

這時候其實畫面上跟之前沒有太多的變化,但是幀數掉得依然比較可觀,現在就是8幀都不到了。

所以通過這麼一個簡單的演示,我們可以得出來,在我們使用光線追蹤反射的時候呢,隨著它的Bounce的增加,它的效能掉得是非常非常的厲害。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

那麼這樣就帶來了一個問題,就是我們如何去平衡這個點?那這個時候我們可以在這個管子的附近加一個反射球,讓它抓取這個管子周圍的一些靜態模型的資訊,然後我們可以通過RT的命令,讓這個渲染的時候,在第二次反彈的時候而採用這個反射球作為一個視覺上的彌補。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

這樣既平衡了我們效能上的不足,同時又帶來視覺上的一個比較好的體現。所以通過這種方式,在很多比如說一些鏡子,金屬比較多的地方,我們可以用。

這個場景也是一個室內場景,我們知道RT其實對於反射這塊,無論你反射的Roughness是多高多低,它都會進行一些反彈。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

但我們可以仔細地稍微考慮一下,如果當我們遇到的這個物體的平面是比較粗糙的,那其實就算它上面有些反射,我們從視覺上帶來的體驗並不是很大,所以這個時候我們可以限制一下它做大的一個Roughness反射的一個值。

比如說像這張圖上面,我們把它小於等於0.2的Roughness值才認為需要參與到RT的反射當中,但是這樣又帶來第二個問題,因為對於一個美術製作人員,就是他如何能比較精準地知道哪些地方的材質Roughness是小於等於0.2呢?是參與到RT的反射當中呢?

所以這個時候我們可以做一個後處理的材質,我們把所有小於等於0.2的Roughness的這個區域,把它以這種綠色形式標註出來。這樣的話,對於美術同學來講可以一眼就會知道,我哪些地方是參與了RT的反射的,我需不需要有這麼多的地方進行反射。

同時這也作為我們一個效能上的控制,可以很好的預覽。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

現在大家看到這個圖是一個材質的節點圖。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

因為我們整個專案當中採用了母材質的流程,也就是所有的美術人員他們自己並不需要製作母材質,只要通過TA做好的一個母材質就直接可以調引數,就可以用了。

這樣的話,我們母材質的一些功能相對來講是比較複雜的,比較多的,但是我們可以試想一下,有個場景有一面鏡子,然後旁邊有一個很華麗的物體,用了非常複雜的材質,比如說一個瓶子,這個瓶子用了很複雜的材質,從鏡子裡面去看這個瓶子。

首先,那麼反射裡面這個瓶子的畫素肯定是比較小的;但是如果我們在反射裡面看到所有的材質效果,依然是沿用了這麼複雜的一個運算的話,其實在視覺上的體驗並不能很大地讓我們能明顯地感覺出來。

那這樣,我們就引入了一個RT Quality Switch的這麼一個節點,也就是說,但我們從反射的物體裡面去觀察細節的時候,我們並沒有讓它完完全全以實打實的那個全節點的運算參與到RT反射當中,我們只給了一些相對來說比較簡單的PBR的節點,比如像Normal Roughness Metallic這樣的值,這樣就會大大精簡我們的一個運算效果。

這邊有個例子,那麼目前在這個鏡子前面站著三個角色,其實我們仔細可以看一下,角色的衣服上面增加了一些細節,我們疊了一些細節紋理。此時此刻我們的RT的Quality Switch並關閉,是開著的,這些黃顏色的衣服上面它也是由這些細節的紋理呈現的。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

但這個時候,我們會看看整個光線跟蹤的反射所需要的的毫秒數是在4.46毫秒,但我們開啟了RT Switch以後呢,我們把反射裡面的黃色衣服上面的一些細節材質就直接幹掉了,不需要再去渲染了。

所以說從畫面上面來看,並沒有太大的差異。但這個時候,它的RT反射所需要的毫秒數降低到了4.1毫秒,今天僅僅是一個小的例子,我們可以想象出如果所有的母材質都應用了這些RT Switch的一些優化節點,在很多大場景中會提供我們很多效能優化的一些節省的資源。

這塊就是我們也用了一些藍圖,把藍圖上面經常需要用到的,有一些RT的引數預設到這個藍圖裡面,然後我們可以把這個藍圖以Volume的形式放到兩個不同場景的一個交界處。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

比如像這樣一個室內和室外的區域,因為室內和室外首先它的光照資訊不太相同,同時它內部拜訪的一些物體的結構、密度、材質也可能差別比較大,那麼我們通過這樣的一種形式就可以在不同的環境下切換兩種不同的RT優化引數。

這樣就會得到整個遊戲性的一個平衡,同時也能滿足一些視覺上的效果。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

最後這塊就是列舉了專案當中常用的一些RT優化的方式、一些命令和一些引數,其實總體來說,就是優化這塊你得犧牲一些視覺化的細節,來換取一些效能上的提升,然後最後去尋求兩者的一個平衡點。

​TGDC | 向陽而生 —— 光線追蹤的專案應用

我覺得無論是光線追蹤還是我們傳統的光柵化渲染,他們的目的其實都是為了將更好的畫面帶給我們,但是自從我們採用了光線追蹤以後,這將為我們開啟一個通往真實世界的大門。

以上就是我給大家帶來的關於光線追蹤的分享。


來源:騰訊遊戲學院
原文:https://mp.weixin.qq.com/s/IQk1q1FnaKwYZpOD0DEp7w

相關文章