search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

遊戲公司做到這些,可以提升遊戲的性能和玩家的體驗

導語:5月12日下午的Unite 2017 Shanghai大會案例分享專場上,技術美術組的李靖著重向技術人員講解了對於製作適應不同硬體設備的遊戲上應注意的技巧和知識,和自己從業了18年來的一些經驗分享。以下是演講原文。

大家好,非常榮幸這次Unity邀請我參加這次分享會。也很高興,跟各位見面。我是技術美術,在這個行業工作了18年左右的樣子,一直是在這個領域,所以可能有些心得,可以和大家分享一下。今天這個題目是怎樣去製作一些能夠自適應不同機種畫面的遊戲,或者是其他的一些多媒體方面的東西。

所以我今天會說到大概有三個模塊,第一個模塊是會介紹一些和硬體,或者和軟體,其實就是和使用環境相關的知識點。然後第二塊,可能會說一些在製作這一類需求的時候,應該注意的技巧和知識,第三塊是我個人在工作中總結出來的一部分工作的一些實例。

不同遊戲畫質對應不同手機硬體配置

我們先從第一部分開始,其實就是,因為現在的手機平台是已經發展了好多年了。硬體的種類應該說是非常之多,多到什麼程度呢?多到這個設備幾乎沒辦法統計了,至少個人沒辦法統計,能力有限。分幾塊,這幾塊都是和我們要做不同畫質的遊戲相關的一些硬體的支持。第一塊就是Soc,Soc是什麼,Soc不是CPU,Soc包括CPU。簡單一點來講,就是在一塊晶元上集成了幾乎整套系統,像高通的,我這邊有一個高通的例子,其實就包括了顯示試配的晶元,包括GPS定位的一些晶元。還有聯發科(音)的晶元,還集成了內存,這個內存非常容易和CPU、GPU封裝在一起,合成一整個晶元然後給到廠商去使用。

這點來說,其實非常之好,但是千萬不要認為,我是手機里只有一個CPU,其他的都是分開的設備。如果是這樣的認為,可能針對性的優化就非常難去實現了。

我們來說第二個,GPU,當年這個領域是列強紛爭,現在能夠存活下來,基本只有這三家,還有在後面會提到的另外一家,這三家,一是Imagination,這是最最有名的,因為它是蘋果設備的GPU的官方授權商。當然它在安卓上也有一部分的客戶,尤其是聯發科,會使用其部分的GPU,另外兩家基本是獨家,高通一個有AdrenoGPU,這是整個ati移動圖形部門收編后新的產物,第三就是ARM自己做的mali。前面還提到一個,相對目前在移動平台上使用不是那麼廣但作為在PC顯卡是行業老大的nvidia,但是在移動設備上功耗我覺得做的還是稍稍欠缺一些,所以說廠家選擇它的可能性比較小。

這裡是和內存相關的,但是我這邊沒有寫內存,而是它的一個極其重要的指標,帶寬。可以看到從2016年到2018年,PC端的那個主流的內存是DDR4,顯卡所用到比較主要,GDDR5,Y軸都是以Gbps為單位的。手機內存會用到的是中間那條綠線,它的內存的帶寬遠遠小於桌面級的GPU,這也就代表在移動設備上,我們開發那些圖像類的作品,完全會受限於帶寬。

寧願犧牲畫質,也要保證減輕對電池的消耗

相對於帶寬指標也重要,就是耗電性,這就是為什麼帶寬在移動設備上不夠大,因為要考慮耗電,手機由電池供電,不是PC插一個電源隨便用沒關係,不是這樣。電池耗盡了,用戶體驗就很糟糕,大家都抱怨蘋果手機、安卓手機都只能一天一充,為什麼諾基亞時代的神話沒有了,就跟我們使用硬體的規格越來越高,越來越難控制,是有關係。這些東西都是一些硬體上的知識,可以對於你做優化有很大的幫助。

有很不同類型的硬體,如果把所有組合加起來會上千種,但是都有同樣的問題就是發熱還有電池消耗,這是一個惡性循環,越發熱電池消耗更快,更發熱電池消耗也更快,然後電池沒電了,遊戲結束了。我們做彈性畫質的目的,其實一部分也為了避免這樣的問題,可以盡量延長玩家的設備的使用時間,在某些情況下,可能會犧牲畫質,或者是其他的方式來實現,所以這個對於用戶體驗來說還是很重要的。

軟體在在IOS和安卓兩個不同的系統上,各有不同的表現力和優缺點

前面大概綜述了一下硬體上的不同,對於我來說那些點需要注意,其實還有第二塊就是軟體上的,軟體的話,首先從操作系統層面來說,是IOS和安卓,目前來說永遠不會變的兩個主題了。兩個系統,其實都不錯,但是完全不一樣。IOS封閉,好處是開發會很容易,因為設備的碎片化也沒有那麼厲害,並且對於後台進程的管理等等都非常嚴格,所以不會產生那種後台的進程在拚命地影響前台,或者說是消耗CPU、GPU資源的狀態。

但是安卓的話,因為比較開放,它可以給開發者帶來很多想象力,可以做很多蘋果上面做不了的事情,確實是這樣。但是它也有缺點,就是它的生態來說,會相對比較混亂一點。可能只有部分廠家會去完全根據安卓的那套規範去做產品。有些不好的小市場,可能會捆綁很多東西,帶來的問題就是你的手機耗電非常快,並且在運行你的前台程序的時候,發現效率往往是和這個級別的硬體是不成正比的。這就是操作系統上帶來最大的問題。

還有不同的是,Graphics API,這是跟驅動僅僅相關,API是需要顯卡驅動,很少有人在一平台上提到顯卡去這個,但是確實存在,任何硬體都是需要軟體去驅動的,只不過不像PC端大家會說,現在N卡、A卡通過升級驅動,遊戲跑的更快了,他們做了一些優化。其實在手機平台上,同樣有驅動這個概念。但是它的驅動是整合在系統裡面,所以一般用戶沒有辦法升級它。所以如果需要新的Graphics API,其實需要驅動的升級支持,比較傳統是PC平台微軟的DirectX還有OpenGL,通過OpenGl我們有一了opengl es版本,但是這很古老了,還是上時代的產物,所以像蘋果及OpenGL基金會都忍不住,也開發了全新的api,蘋果的是Metal大家都在用,Iphone5S就已經支持。OpenGL基金會開發出的新api vulkan也已經出現在今年的新設備上了,這些新時代的api給大家帶來的好處就是,可以提供新的畫質上的提升點,同時還可以提高渲染的效率,這可以讓電池耗的更慢,這個外面有一個Mali展台,他們有這方面的展示,就是解釋這個能源消耗的一個問題。

Unity在安卓和IOS上帶給了我們很多共通性

軟體有很多不同,Unity帶來給我們什麼,Unity帶給我們相同的語法,這個幫助極大,如果用其他類型的編輯器引擎的話,可能就要維護多一些,這個成本其實是非常可觀的。它的語法很簡單,先定義屬性,其次subshader塊,再通過標籤,通過pass來區分,渲染的順序,包括渲染的狀態等等。

綜上所述,尤其是安卓設備,也包括蘋果,(蘋果的設備已經有十年了,大家很期待十周年版Iphone,其實已經有很多分支了。)那麼多分支,首先我們要預知到,當前的硬體設備是屬於哪個級別,如果知道了,你可以進行下一步操作,針對不同的因素,可以做減法,或者針對更高的,可以做怎樣的加法,所以首先IOS比較簡單,Unity本身就提供,你只要用這個函數返回一下就知道當前的設備是什麼,是屬於第幾代Iphone,或者第幾代Ipad,對於安卓來說,跟前面說的生態有直接的關係,就一下子變複雜,話題很沉重了。

但是Unity提供一部分的功能,你可以通過UnityEngine.Systeminfo可以獲得想要的東西,包括CPU,最大的顯存,包括CPU架構,CPU的頻率這一類,但是其實你光用這一類,這些東西綜合出一套自己的演算法,來評估的話,其實還不夠。我覺得最總重要的是通過維基百科這個平台定義一份自己的表格,這是最重要的,這邊可以給我顯示一下表格嗎?因為現在大部分遊戲都有配表,這是一張設備適配表,大家看第一屏,第一屏是把它分成了有叫設備,還有是GPU,後面有一個LV,然後是註釋,這都是IOS的設備,大家看我分成這些檔。因為IPhone每一代都是一個SOC,通過查維基百科上,這一類的GPU的Gflops是多少級,這是第一點。

第二點,它支持3.0還是2.0,顯存最多有多少,通過這一點,我可以得到一個結果。現在分類是,大家可以看到LV有一些負一,負一的意思,在我這邊其實就是我測試機最低標準以外,可能會有不兼容的狀態,並且他們都很低端,都是opengl es2.0。我開發的一些圖形上的特性,可能使用的都是es3.0以上,這些機器基本上可以排除掉。或者以後,根據需要進行支持,通過寫一些擴展,或者其他的方式,來增量解決兼容性的問題。現在最新是iphone7Plus,顯示的效果會不太一樣。Ipad也是一樣,也是同樣的一個邏輯。

大家看到,設置這一欄沒有東西了,因為安卓你如果去用設備來分的話,你這個表就非常非常長,可能上千,甚至於上萬,我覺得沒有意義,並且不可能統計。我用GPU來統計,GPU統計相對容易一點,尤其是高通和power vr,高通每代對應的GPU是不一樣,能很清楚這個相對應的SOC是什麼,大家都知道,今後因為蘋果和power vr合同解除的關係,imagination必然越來越加強安卓陣營的投入。聯發科的新soc Xelio30,包括其他後續的產品,很多都是PowerVR GPU,還有Mali的GPU,這個也很容易區分,高低的檔次,像mali 400系列,T600系列,T700系列,包括現在的GT系列,非常容易分,但是為了更加精確。

所有這些信息,包括廠商,SOC細節等,在wikipedia上都有,我認為有想法的人可以整和成更完美的表格。譬如打開wiki就可以查到,現在的SOC,都什麼製程,GPU核心是什麼,等等都能取得,通過這個有一個非常好的,比較詳盡的檔次表。光有這點還不夠,還要去使用自己算的表格,如果這些條件都沒有達成,那這個機器怎麼處理,譬如新出了Iphone8,廠商沒有及時出更新自己的表格,這邊認出來就是Iphone unknow,所以需要再制定一些規範,這個cpu主頻怎麼樣,內存有多少,這些方法來決定這台機器可以顯示什麼效果。

不要著重於某一塊,硬體配置要均衡

前面關於軟硬體的這個環境的這塊,基本上都講完了,其實最最重要的是,首先知道差異化,並且知道這些東西和圖形渲染是直接相關,可能不一定需要知道太多的細節,因為並不是硬體工程師,也不是做系統,也不是做驅動的,我們是做產品的。需要能夠判斷出什麼是好硬體,什麼是壞硬體就可以了。免得盲目的優化! 這邊其實也要稍稍吐槽一點,就是國外的硬體商相對硬體比較均衡一點,但是國內的稍微偏激一點,在某一塊會做的比較主打,我這邊是10核心的CPU,很棒,但是不提GPU,可能GPU就不是那麼好。主打什麼,那塊肯定沒問題,其他都是短板,這就造成很多機器的綜合性能並不高。

說到短板,到了第二環節,我們要做的是什麼?我們要做的是讓整個渲染的效率,不管從任何的環節來說,從任何面上來說,是沒有木桶效應,一旦有木桶效應,就有瓶頸。其實最最常用,每天都會用到的工具就是Unity中的Profiler,這個非常好用,因為能看到非常多的信息,並且能夠有一個大致的評估範圍,比如說CPU裡面,CPU這一塊到底是什麼東西比較費,是Rendering比較費,還是腳本比較費,還是物理比較費,都是非常明確顯示在裡面。並且CPU這塊還能通過把左下欄那塊表,細分出到底是什麼函數比較費,可以做一些定位,如果切成另外一個界面。現在這個叫Heiruke(音),如果工程設置裡面,設置成多線程渲染,就能看到現在的情況到底是CPU在等GPU,還是GPU完全不是壓力,壓力全部在CPU,因為多線程,渲染線程是分開,並且有一個事件waitingforpresent,這個事件告訴其他硬體gpu當前在忙,你就等我吧,等我結束了就告訴你了。通過這個例子其實很容易知道,當前開發這款產品,我是邏輯上出問題了,還是渲染的東西過多了,已經超過這個GPU能夠承受的範圍,很容易判別。

包括Rendering,也會提供很多消息給我們,如果說我發現我們渲染的東西,GPU並不是很費,大部分時間都在CPU,看一下Rendering,這個也非常高,是不是沒做batch(音),或者渲染的東西有問題,或者超標了,都會有問題。這種東西好處還在於可以連到真機進行調試,可以直接接上iphone,或者接上安卓都可以跑。像powervr的顯卡如果頂點流超過範圍,就會繪製兩次,那時間就是雙倍的,所以能看到詳細信息。內存和我們這邊就關係不大,略過。還有物理的也是一樣,物理的話能夠看得到,當前的激活狀態的有多少,當然越多越費。但是這邊也要提到一點,你是不是簡單的造型,如果都是複雜的造型或凸面體當然很費,如果是簡單的造型其實都還好。

除了Unity內置的Profiler,如果需要更詳盡的數據,(安卓選擇最多)我這邊推薦不是三大廠家的,而是Nvidia Tegra Graphcis Debugger,這個好處在於可以很容易查看一幀繪製的整個過程,並且可以看繪製的結果,就和Unity中的有一個功能是很像,帶來的另外一個好處在於,你可以即時修改shader,這個時候就沒有Unity的幫助,你得注意自己的語法,是GLSL的。還可以通過一些簡單的參數的測試,比如說我不知道我現在的渲染的瓶頸到底在哪裡,我試試看,把所有貼圖就換了,點一下texture替換為2x2像素試試,啊就可以了,發現幀數好了,那我知道了,我的貼圖有問題,貼圖換成2乘2代表什麼,代表你的帶寬被撐滿了,內存來不及傳輸了,你就知道針對點了,也知道應該怎麼去干,對於比較低端的平台。

在渲染上需要解決除了Profiler工具以外的知識點

還有的話,比如說我把深度測試關掉關掉,不比較Z,總之可以通過這樣的排除法來替換,能知道我這個場景,我這個產品到底有什麼問題在那邊,這是一個方法。

當然另外三大廠商的GPU也可以用,只不過會相對來說,麻煩一些,但是其實他們的用途作用都是一樣的。除了使用Profiler工具以外,我們還知道一些知識點,只有這些知識點都被解決了,你的渲染才不會成為整個遊戲的瓶頸。第一個其實解決Draw-CallS和batches,就把Unity中的標籤打開,Unity在運行的時候,就會把這些標上Static的東西合併成一個,這個其實也是要看情況使用,不是說你把整個場景所有的東西全部合併效率就是最高的。因為我們還要考慮到一個內存的問題。因為Static batches有一個內存拷貝的問題,會生成另外一份合併的內存,原來的資源都是在的,會生成一個新的。一般不會佔用太多,但如果做的遊戲是針對非常非常低端的設備,可能內存本來就非常捉襟見肘。第二比較多的就是Dynamic batches,這個限制非常多,能夠符合標準的那些物件,就是他們的材質是相同的,然後他們的transform,X、Y、Z ok,並且它們小於900 vertex attributes,非常嚴苛,就可以合併在一起。現在有一個方法是Instance rendering,使用相同的材質,可以批處理,這個其實是api相關,Opengles2.0就是不支持,我們可以使用這樣相對比較高級的方式。但是這個需要大家去改動shader,才能實現的。標準的Unity裡面有專門的shader支持instancing,這些可以做到批量繪製,但如果使用自定義shader,就是需要自己去維護。

還有一個渲染的優先順序來說,static模式最高效是最快的,第二個來說是instancing rendering,最後是Dynamicbatches,所以使用優化技術的時候,大家可以有一些側重點。

第二個支持點,是Overdraw,其實就是屏幕重繪,這是很可怕,因為業界還沒有完全解決這個辦法,因為和當前的圖形學的基礎優化方案是直接有關的。原因在於不透明的物件,renderer會寫深度圖,第二個不透明的物件,在畫的時候,會比較深度,只有在深度合適的情況下,沒有被剔除掉,才會畫。但是透明不一樣。透明因為不會去寫深度,也就是你在屏幕上能看到多少透明,就畫多少遍,可能會非常多。比如說我們做一個很簡單的例子,往這個遊戲攝像機的面前,扔一顆炸彈,這個炸彈其實在遠處爆炸的時候,效果挺酷炫很棒,也不是很費。但是扔到屏幕前,可能就直接爆炸了,我是指設備爆炸,不是指炸彈爆炸。一下子把很穩定的35幀變成兩幀三幀,這種情況都遇到過,針對這種問題,第一在製作的時候就嚴格注意半透明的層疊的數量,注意他們全部展開之後的總的像素的數量,這是很重要的一點。

有一些方法規避掉這些現象,避免在鏡頭前出現非常多的半透明的,並在遠處顯示。

Shader對性能產生的影響

還有一塊會對性能產生極大影響,就是Shader,Shader是今天比較重點講到的東西,shader在Unity,現在是兩類surface shader 及 vertex fragment shader,surface shader它可以在非常頂尖的主機如Xbox1上跑流暢,也可以在PC上這種狀態下有非常好的效果。但是針對手機遊戲的話,surface shader雖然做了非常多的優化,但是因為太通用,所以還是比較費,我個人主張,是對於手機平台的話,盡量使用vertex fragment Shader(音)。

像素剔除默認就是把背面裁掉,但是有些情況,比如寫了一個草的Shader,正反面都能顯示,但是美術把這個shader用在建築上,內部永遠不會看到,這樣的狀態會導致有些情況下是兩倍的輸出,這個還是需要注意的。畢竟移動設備的GPUshader的流出率不是那麼高,計算也差一些。

接下來還有還是需要佔帶寬,會不會太多,導致帶寬佔滿了,但是如果說,額外的深度操作就可以佔滿帶寬。舉一個例子來說,就是我所有東西都是不透明的,然後我畫陰影,另外一個攝像機不同的角度,要重複畫一遍深度圖,那就是額外的帶寬,可能就會導致翻倍。或者也有可能讓你比較低端的機器的帶寬就撐滿了,就做不了其他的事了。

還有一點是Ftime(音),如果這個設置不對,雖然是不可見,但是開銷是實際存在的。

還有一點就是疊加的模式,一旦你用疊加模式,也代表這個東西,一般是不太會有,因為這種情況非常少,你做半透明,你這個半透明後面被遮擋的東西,就沒有了。你看到就是一個非常奇怪的景象,除非你需要這樣的特效。

關於頂點計算、Mip-maps和貼圖大小應注意的地方

下面有幾點建議,就是儘可能把所有的計算放到頂點計算中,因為頂點計算比較省,而且現在的GPU,既能處理頂點,也能處理像素,因為就幾年前,其實這些處理環節還是分開的。就是頂點的處理器是分開。大家都知道,像素的輸出永遠永遠會比頂點要多得多,如果說我把所有計算都放到頂點上。頂點到像素之間做一個差值計算,就和你怎麼說呢,一個點到另外一個點中間,線性做一些多度,類似這樣的方式,把這個計算的結果,轉換到這個級別,很多計算可以做簡化,在這塊,把它放到頂點。並且保證這個足夠強大。

現在手機雖然屏幕不大,再大也就是6寸7寸,但是像素的密度極高,解析度非常高,2K,現在很多是2K的手機作為一個賣點,至少是1080P,可能的手機是720P。但是就算是1080P、720其實也是非常大的代價。1080乘720是多少像素點,如果屏幕上繪製三遍再乘3,這就是開銷,直接可以公式化。還有一點盡量自己寫,在有時間有這個預算的情況下,這個可以讓你的效果表達更好一點,或者走的更節省一點。

這邊的話又提到帶寬這個詞,從這幾個點來說,都會帶來帶寬上的問題。第一個是貼圖的Filtering,就是過濾器,過濾器越高級,其實從3D世界,遠近的角度來說,貼圖做的越小,還原度會越高,並且和近處的高分辨里率的貼圖之間的,就是過度的更平滑。但是帶來的代價就是它是多重採樣,並且有比較複雜一點的計算,而且這個沒有太大的關係。因為這個是硬體級別,是直接可以處理的,但是會佔用帶寬。

第二點是Mip-maps,在安卓上是有意義的,powervr的gpu上這個幫助會有一點,但是非常少,沒有關係也不大,應為使用的渲染方式是deferred tiled base rendering,所以一定要注意這寫問題,當然我指的都是3D物件的貼圖,2D其實很多情況下大家都不用mipmaps,純粹就是浪費。

還有就是貼圖大小。貼圖大小,不光是占顯存,還導致一個問題,就是傳輸會變慢,越是大的貼圖,cache miss率會越高,導致傳輸效率更低,這都是惡性循環。還有一點,就是我們自定義的一些後期渲染用的postprocess,這個越少越好,這也就是為什麼目前為止,比如說Unity到現在為止,沒有建議可以讓延時渲染這樣的技術,跑在手機上,其實就是因為手機帶寬永遠不夠,根本跑不動,那麼高解析度,同時3到4個gbuffer,沒有那麼大的帶寬。

關於帶寬上的細節注意

帶寬這個問題其實是在渲染的時候是經常會出現的一個瓶頸上的東西。我以前做主機類的遊戲比較多一點,帶寬很大,Xbox1的esram帶寬非常大,但是內存很少,我們為了把一個遊戲用延時渲染的方式需要的gbuffer塞進去就需要做了很多優化,用些技巧,如果放到主存,雖然能用,但延時就非常厲害,沒有實用性。ps4用的主內存速度比較好,可以用全尺寸gbuffer,大家在手機上如果一定要做延時渲染,理論上來說也是可以的。但是只能用非常低的畫面解析度,所以大家不可能接受,這個畫質會非常差,帶來的好處不足以去彌補那些不好的地方。這邊也提到了這個,這是前面說過的。

第二個節點,基本上就是聊了一些知識點,這些知識點都是對於我們做彈性的畫面是直接有影響的。其實我在設計整套系統,自己也會設計這樣的東西,也會考量前面的點。現在就講一下,我在莉莉絲這邊實現這套系統的一些想法。這個功能,其實是有一個切入點,這個切入點在於guality setting,它這個可以把遊戲的畫質分為,是Fast、Good、等等,可以控制一些東西。第一個是pixel lighting接受的數量,在forward渲染的模式下,你的物件就以多pass的模式畫下來,這樣的話效率很低。在我這邊的demo裡面,低配全部是零,最多有一個,不包括太陽光,這還是需要。第二個貼圖解析度來說,有兩個選項,第一種是全尺寸,第二是半尺寸,半尺寸在有些情況下解決帶寬的問題。還有就是一些過濾方式,是不是基於每張圖都做,還是強行都關閉,這個需求而異都可以。

還有就是soft particle開銷很大,會有額外的深度圖的輸出,其他的有一些選項開銷都不是那麼大所以沒太大的關係,reflection probes我現在這個工程裡面,我是沒有去用到它,其實就是做一些反射的點,可以在場景裡面有很多,並確實是實時更新這些probes,對CPU的負擔肯定是很大的。然後還有下面這一塊,在我的例子裡面,shadow全部是自己實現的,所以在高中低配,把這些全部都禁掉。

還有其他的選項,也會有幫助。像第一個是bone weights,這個是對於蒙皮的骨架數量控制,如果你用CPU蒙皮的話,這個選項的作用就很大,可以控制這個頂點到底由是多少個骨架

影響,最終來實現那個運動。

第二個是vsync,vsync手機上一般都不會去開,因為雖然可以幫助畫面不撕裂,但是造成的問題是讓幀數就要跌直接跌5幀以上,造成明顯的卡頓。還有一點,我用比較多的是LOD Bia和Max LOD,這個我在後面會說到。包括Paticle 射線檢測方面的這一塊我會降到很低。

還有下面就是非同步載入的時間切片,你使用腳本去調用資源相關的東西,這類東西的話,目前在我這個Demo裡面沒有使用。

先說說第一個,第一個其實就是LOD,這個其實對應的是前面那個LOD Bias裡面的。LOD有幾種,第一個是顯示模型,就是和顯示相關的物件,一類是靜態模型,一類是蒙皮模型,就可以添加一個LODGroup的組件,有了這個之後,可以有多個模型,根據距離切換顯示的等級,可能是越遠越簡單。通過LOD Bias可以控制這個係數。在最高配的機器上,可能50米以外才會切到第二個等級。但是如果說對於非常差的設備,我會把這個係數傳的非常小,在5米以外就變成另外一個模型了。對於Particle來說,這塊同樣是適用的,使用它的話,就把一個完整的Particle system切成不同的分類,使用這個LODGroup,你可以在近距離的時候,顯示的是相對精簡過的。為什麼與模型的方式不一樣呢,這和overdraw相關。因為相對鏡頭最近的,比如說十米以內,不允許有很複雜的overdraw,必須很簡單。十米到50米之間,全效果,50以後慢慢再精簡,類似於這樣的方法,可以既控制(英文),也能夠讓你的例子,在大部分的狀態下,顯示出完整的效果來,通過這種方式,這是一類。

但是這類方式也有一個問題,就是所有的這一類,換了LodGroup,必然有一個計算距離,有什麼辦法可以一勞永逸嗎?有一個小技巧,這張圖上寫的,有一類叫decorations,純裝是的和這個遊戲本身的關卡、結構沒有必然的聯繫,一類東西。我把它全部放到一個節點上,在低配或者中配的情況下,把部分的節點關掉,下面所有的東西都關掉,就不要顯示浪費性能了。

Unity的ambient和陰影效果

然後自己再寫一點比較有擴展性的東西,我在這邊,我把它擴展出了幾類,在遊戲中,我們的遊戲人物比較小,在遊戲上很小,所以這個人物不是真實的,但是會拿一個燈光的方向,根據matcap來算出受光面和背光面的效果,所以有人物這一塊。然後還有全局上來說的話,我會使用到場景裡面的ambient,但是Unity的ambient會比較多一點變化,比較複雜,所以我們直接提出來,這樣的話可以做到,在遊戲中,在不同的區域,可以有不一樣的效果,它們互相之間可以轉換。

還有一類是shadow,因為我shadow完全重寫,所以這塊的話,我這邊的設置全部在這邊。還有一個反射源,我會Unity的reflection probes來生成出需要的資源,有時候會自己手動放一些cubemap在裡面,在不同的區域,可以通過把這些做差值,計算出你到底是離哪一個點更近的混合的效果。這個其實可以用在很多種形式上,就是比較簡單的反射的,水面或者PBR都可以用到,還有基於頂點的,可以放在這兒。

還有這個面板是每個場景,都會有一個,當然也可以有多個,你只要放在那個,每個區域放一個,並且標記好位置,區域也是可以的。這樣的話你在不同的位置,可能你全片濾鏡是不一樣,我這邊還有一些全品濾鏡的調整。

這邊其實就是這邊也要寫LOD,這個語法很簡單,就是利用Shader Lab中的一個LOD的標籤,這個有很多好處,第一個是兼容性很高,這個兼容性其實是兩方面的。第一方面來說是只對於美術同學它的兼容性很高,不用高中低配,為了不同的模型指定不一樣的模式,就是做其他的修改,只需要一個材質,這個材質自帶LOD,你為這個材質所做所有變化,對於所有的低級的LOD都是有意義,這是一種方式,兼容性上的好處。

第二種好處來說,因為這是Unity自帶,因為Unity原生的shader都有標好了級別的,這個上官網,幫助裡面都有,你可以和你的評估值和他的值的對比,複雜程度自己做下比較,評估測試一下自己的shader,讓你的消耗程度和他寫的某種shader差不多,這樣的話你的場景中,可以不需要全部自己寫shader了,一部分的可以用原生的,一部分用自定義的,就可以解決兼容性的問題。

第二個來說,非常容易擴展,因為LOD隨便定,所以容易擴展。

第三個的話是切換很方便,切換其實就是用到了Max LOD開始的時候,quaity setting的面板,只要把中間那個max LOD的值改了,就自動切換了,所以綜上所述,它很靈活。但是它也有缺點,缺點就是現在變的冗長,修改起來,一下子修改多個LOD,第二塊來說,會稍稍多佔一點內存。

這邊其實很簡單,就是提了一下,也可以用Script方式可以切換,所以含這些的,包括的物體,這類物體的Shader會變成另外一種狀態。

但是有一點注意,因為寫shader的時候,經常碰到一個兼容性問題,尤其寫一些,和API相關的東西。其實兼容性問題都來自於兩點,是D3DLike還是OpenGlLike,

主要不同點一個是切線是不一樣,還有深度方向是相反的。然後數值的精確度,這種全精度、半精度類型等,可能某些Shader對數值精度會很敏感,千萬注意這些問題。還要千萬不要忽視PC,我一開始寫這些東西,經常碰到的問題就是在真機上一切都OK,PC上會報錯,因為Unity都是有支持的。那麼它的shader在一個PC,並且裝了比較高版本directx的,(DX9以上),那這個shader compiler是不一樣的,會嚴苛很多。所以需要花更多的時間去維護。

渲染的後期濾鏡

最後的話,還有一些小的技巧上的東西,我覺得也挺重要的,第一個是後期濾鏡,一定要把後期濾鏡的合併起來,因為unity的標準資源包中,包括了一部分。但就算用官方的,也是可以合併在一起,這樣可以節省rendertexture的數量,在一幀中不同階段的重用率,這樣帶寬佔用就少一點。第二盡量使用Unity提供的宏。因為用了shader的LOD及宏控制,一定要放在Shader Variants的容器下,並且掛載到quality setting中,這些shader在一開始就被預載入,雖然內存多那麼一點點,但是在遊戲中不會卡頓。還有就是要注意透明,還有一個就是在有可能情況下,可以使用一些culling的方式可以自己寫一些Cullin給的方法,因為unity都有開放介面,或者使用官方的occlusion culling。

這個就是Demo本身,這個屏幕很大,大家會看到影子是畫兩層,如果說放在一個非常高ppi設備上,這兩層影子就變成軟陰影,這本身是一個PBR材質的Demo,現在是最高級別,大家可以看到會有景深,會有bloom效果,還有PBR所有反射還有影子等等,這是降一檔,其他效果都還在,還有影子變成單層,法線貼圖沒有了。再降一檔(我這邊有意做的區別很大)反射沒有了,變成這樣了,然後後面那些塑料球的質感變化不大,影子變成不受你太陽光的角度控制,變成了垂直的,因為這樣是最省的。

然後再往下,高光也沒有了,影子也沒有了,再往下,只有頂點光和貼圖。使用到相對比較實際的情況下,是這樣,差距沒有前面看到那個Demo那麼大,這個是全效果,往下,並且影子那邊那輛賽車上只有影子,自投影和地面投影,都有一個影子,再往下動態投影沒有影子,並且反射關閉了,但是specular還是在,再往下lightmap還在,其他東西沒有了。最後一級,是頂點光照,這些可以寫成各種各樣不一樣的樣子,可以做的就是會更好一些,或者說是差距再大一點都是有可能的。

今天的話,我分享的內容就全部到這裡,時間有限,謝謝。



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦