天天看點

【Unity Shaders】Reflecting Your World —— 在Unity3D中建立一個簡單的動态Cubemap系統 寫在前面 準備工作實作解釋更多……

本系列主要參考一書(感謝原書作者),同時會加上一點個人了解或拓展。

是本書所有的插圖。是本書所需的代碼和資源(當然你也可以從下載下傳)。

========================================== 分割線 ==========================================

我們已經學了很多關于反射的内容,但是我們現在的反射并不能實時反射,即當反射物體移動時它們不能正确反射周圍的環境。例如,如果你有一個由很多房間和走廊組成的環境,我們不可能提前渲染所有的cubemap然後放到一個cubemap中。這意味着我們不能随着房間的移動而正确反射。我們得到的是一個靜态的、令人乏味的反射效果。

有很多方法可以解決這個問題,即一個房間的反射不同于另一個房間的反射。一個最基本的方法就是根據在房間中的位置替換cubemap。是以,當你從一個房間移動到另一個房間時,cubemap應該被換成目前房間的cubemap。第二種方法是當我們角色在環境中移動時,實時更新cubemap,最終在遊戲進行的每一幀得到一個新的cubemap。盡管第二種方法聽起來非常吸引人,但是它比較消耗性能,是以你需要在其他遊戲資源之間進行權衡。

這一篇将會講述第一種方法,并且向你展示如何搭建一個非常簡單的系統來基于你在環境中的不同位置去替換兩個cubemaps。更多的關于實時反射系統的内容你可以在本節最後找到,是以如果你對實時反射感興趣并且想要看看兩種技術之間的差别,你可以在那裡找到!

我們需要建立一個新的場景、一個新的平面以及一個球體。除此之外還需要一個平行光。

繼續添加兩個空對象,并分别命名為pos001和pos002。

給球體添加一個新的材質,并使用fresnel shader(上一篇)。這樣你的場景應該看起來像下面這樣。

最後,建立一個腳本,并命名為swapcubemaps.cs,把它賦給球體。

最後的準備效果如下:

【Unity Shaders】Reflecting Your World —— 在Unity3D中建立一個簡單的動态Cubemap系統 寫在前面 準備工作實作解釋更多……

首先在類名之前添加[executeineditmode]:

聲明一些變量來存儲系統需要的變量。我們将在下面解釋它們的用途。

為了可以直覺地看到cubemaps所在的位置,我們需要利用unity3d提供的gizmos 。是以,在腳本的最下方添加下面的代碼:

現在,我們需要建立一個新的方程來決定在不同的位置我們應該使用哪個cubemap:

最後,我們僅僅需要每一幀的時候計算物體距離每一個預定位置的距離,然後為球體的material替換合适的cubemap:

儲存腳本,傳回unity編輯器。當編譯完成後,點選play按鈕,并前後左右移動球體。你将會看到類似下面的效果:

【Unity Shaders】Reflecting Your World —— 在Unity3D中建立一個簡單的動态Cubemap系統 寫在前面 準備工作實作解釋更多……

一開始,我們為類聲明了[executeineditmode]屬性。這将告訴unity我們想要在編輯器狀态時也運作我們的cubemap替換腳本,而不僅僅是在play狀态。這可以使我們不需要點選play按鈕就可以檢驗cubemap替換的腳本——這很友善不是嗎~

這個腳本包含一些變量,包括兩個cubemaps和兩個位置變量(用于比較距離),我們需要提前指派給它們。最後我們需要兩個私有變量來追蹤運作時刻目前的球體材質和cubemap。

當我們給四個共有變量指派後,就可以使用内置的ondrawgizmos()函數來真正顯示兩個空對象(位置對象)的位置。這些位置将會指導腳本什麼時候去替換cubemaps。

然後我們來看一下腳本中真正替換cubemaps的函數。我們聲明了自己的函數checkprobedistance(),它将使用vector3.distance計算球體和其他兩個位置點的距離。然後它檢查哪個距離更近,并傳回那個位置對應的cubemap。

最後,在update ()函數中我們得到目前球體的材質,或者其他該腳本指派的對象,然後根據傳回的自定義cubemap來指派給該材質。

這僅僅是一個非常簡單的腳本來參數這個概念,但是它可以被擴充成一個完整的系統,例如你可以每一個房間對應多個cubemaps。這個系統可以實時自動生成所有的cubemaps(但不需要每一幀都生成),這對于無法進行完全實時反射的遊戲系統将非常有用。

你還可以看一下,如何建立一個實時反射系統,在這樣的系統中每一幀都需要渲染更新cubemap。這的确是一個非常吸引人的系統,但是需要以犧牲性能為代價: