天天看點

在頂級遊戲開發的過程中需要怎樣的程式設計實力?

做遊戲技術主要講究的是套路,以及對套路的掌握程度。比如說你要搞個體積光,那麼從用mesh+uv動畫,到volumetric scattering你都得知道,而且要知道這些方案的優缺點,以及具體的實作細節,比如camera會不會到體積光裡邊之類的,這種細節的了解會讓你更加有信心做出各種技術決策。

是以3a級遊戲的大神技術也是對各種領域的套路玩得比較溜,這裡我也分享一些做遊戲20來年自己領悟出的一些套路吧。

美術用工具輸出的3d模型,材質一定要做一個導出插件,否則做出來和進引擎效果不一樣,就隻能做做手遊這種無光照的手繪貼圖品質的産品了。

動畫要想不滑步,就隻能用animation driven的方法,這個需要跟策劃做好深度的溝通,得讓策劃知道移動不是說配置一個速度就可以了,得去找動畫師一起調整移動的動畫。

動态天氣的困難不是制作上的困難,是可以用lightmap的物件會少很多,性能不一定扛得住,這個要在項目初期一定得和制作團隊溝通清楚。

球類遊戲要達到非常自然的動畫,一方面動畫肯定是要動捕的,另一方面更重要的是搭建一套動畫選擇機制,然後根據運動中的球類位置來選擇最合适的動畫來比對,再加上小部分的ik。

頭上冒字和冒血這種hud就應該用hud的标準方法來制作,切記不能塗省事用ui的方法,對性能效率會有非常大的影響。

音頻對最終品質影響很大,一般遵循46原則,即圖像資源在最終包中占6成,音頻資源占4成。給音頻設計師配置一個獨立的程式來達成音頻的設計需求。

狀态機最好是用可視化的方法來實作,遊戲中80%的bug都是和狀态沒切對有關,有個可視化的狀态機對于找bug非常友善。

control是最需要狀态機化設計的(不同的情況下按同樣的按鍵達成不同的邏輯)

做面部表情,如果不是捕捉就用骨骼簡單搭搭就好,如果是捕捉,制作成本會變得非常的高(制作各種morphing target)

對最終畫面影響最大的是鏡頭效果,是以盡量節省渲染時間留給鏡頭特效。一般影響最大的是校色,如果硬體平台允許盡量給美術提供帶深度校色的工具。

有比較寬廣視野的遊戲,室外可以用一些很取巧的方法來模拟mie scattering和rayleigh scattering,加上哪怕是假的對畫面的提升也是巨大的。

對于不同的資料采用不同的配置方法,不要什麼資料都用excel,對于有可視化需求的配置,比如ui或者角色身上需要裝配一些武器的,提供可視化的工具。對于需要描述父子關系的例如技能樹解鎖之類的用json或者xml來描述,對于純數字邏輯的就用csv就好了。

場景的材質如果制作normal map對于你們團隊比較複雜,多加一層detail map也能對效果獲得較大的提升。

角色的材質,如果性能有限或者說制作成本無法承受的話specular map比normal map的效果要好。

如果角色會近距離看臉,臉部的眼睛一定要單獨拿出來處理,臉可以糊,眼睛一定不能糊。

腳步聲的标準做法是在地面上放一層低模做和腳的碰撞檢測(腳步聲如果追求真實,最少得有3個以上的樣本随機)

如果要提升動畫效果,考慮主角的前臂加上twist骨骼,左肩和右肩不要從脖子上搭建骨骼,要從胸口開始(做head lookat的時候效果會更好)

衣服的标準做法是通過貼圖來控制哪些頂點受skin和實體影響的權重比,那張貼圖還可以用一個通道來控制流汗的時候哪些地方的smothness要提高。

搭建一個運作時資料庫,并且遊戲中經常需要通路的資料都放入資料庫,可以類似redis那樣非常簡單的提供一個set和get就行了,運作時資料庫可以幫助你找到絕大多數bug。

制作ai盡量使用行為樹,并且花時間一定要讓策劃具備編輯和調式行為樹的能力。

頂點色可以各種花式使用,無論是用來bake ao還是決定detail map的權重,都可以用很低廉的代價來獲得非常棒的效果。

動畫不是在任何時候都可以blend的,要想效果好,牢記:左腳落地的時候隻能blend到左腳落地開始的動畫,右腳同上。

做上下樓梯的locomotion的時候,用橢球碰撞體會非常簡單的獲得還不錯的效果。

如果畫面會經常快速的運動,可以加入一個vector based motionblur,效果會出奇的好。

要想場景生動,一定要使用decal,一個友善美術的decal工具可以讓美術一天之内讓整個場景提升幾個檔次。

暫時想到這些,不說了,休息好了繼續幹活。

~~~~~繼續更新一波套路

解決alpha透貼排序的标準方法是兩次繪制,第一次在不透明隊列裡渲染一次alpha test(cutout),打開zwrite,第二次在transparent隊列裡開alpha blend不開zwrite,ztest lessequal渲染就能還原美術在maya裡看到的效果。

彈簧是個非常好用的實體元件,其虎克系數可以有效的模拟力的衰減來做出很多感人的效果,從乳搖,臀搖,尾巴,頭發馬尾,布料,臉上被重拳擊中的肌肉變化都可以看到彈簧的身影。

adobe fuse cc + mixamo可以非常快速的搭模組化型和動畫來幫助策劃找到劇情的場景的感覺。

腳下ik從程式來講是很友善實作的,大多數引擎都有ik功能,但是工作流程我發現很多公司都沒有正确使用。正确的流程是對輸出的動畫有一個左右腳高低的分析工具,逐動畫生成每個腳步離水準面的高度曲線,然後運作時根據腳步的高低來決定ik和skin的權重。

鏡頭的設定很重要,最好給美術一個和相機鏡頭類似的算法來反過來計算fovx和fovy,我看到很多産品的fov都是一水的60之類的。

對于類似鐵絲網或者其他半透物體的mipmap的标準做法是先自動生成mipmap,然後要美術手動的來降低不同lod貼圖的alpha,換句話說近處看有鐵絲網,遠看就隻有框中間近乎全透了來降低鋸齒感。

dx10以上的平台上特效的shader加一句根據目前depth和已經繪制的depth的差來控制alpha可以實作簡單且效果不錯的軟粒子效果。

頭發的實體效果可以參考衣服的做法,發根受skin影響多,發梢受實體多一些即可。(額前劉海受實體要關掉重力)

如果實時sss負擔太重,可以簡單的把模型厚度資訊烘培在頂點色的某個通道上,然後隻需三兩行代碼就可以讓皮膚有sss效果。

看到好多項目用雙面材質隻是在shader中簡單加一句cull none,這個是完全錯誤的實作。正确的做法是需要把三角形索引資訊走vs傳遞進來,然後判斷是否順逆時針,對于反面需要把法線反轉才能獲得正确的渲染結果。

先更新到這。

完了,感覺思緒開始打開了,又更新一些,怕一會會忘。

動畫驅動的模式下,轉向最少需要8個動畫,原地左轉90,右轉90,左轉180,右轉180,移動同樣四個,然後根據控制器的輸入來決定混合的權重,一般神海這種級别的産品光locomotion牽扯到的動畫會在40-50個這種量級。

對于衣物和皮膚,detail normal十分重要,可以瞬間讓你的衣服能看出針織的材質。

處理聲音的時候,遠處的聲音混響需要程式來手動提升,近處降低混響,對臨場感增加很多。

聲音如果樣本有限,也一定要做随機,哪怕就一個腳步聲樣本,播放的時候也應該随機pitch和volume。

給策劃提供一個調整動畫曲線的工具,橫軸是動畫時間,縱軸是動畫播放的速度,策劃通過這個工具可以調整出情緒非常飽滿的動畫效果(例如:攻擊前搖動畫速度變慢,攻擊過程加速之類的)這個需要和動畫師溝通清楚,要求他們隻需要k好幾個相關pose即可。

卡通渲染的時候有一步是非常關鍵也是很多公司都忽略的,就是手動調整模型法線,這一步得在美術工具内完成,通常是定義toon shading的光方向之後,通過調整法線來讓一些部位有“看起來”較為舒服的受光,主要是鼻子,腋下和兩個胯這三個位置。

遊戲加載的正确做法是,在出包的時候對各資源的機關加載時間進行預計算(适合配置固定的主機遊戲)。之後在運作時加載的時候,根據每一幀cpu的可用空閑時間來決定目前幀可以加載的資源類型和數量。

渲染陰影的時候,很多人都會忽略繪制陰影那個pass的優化,以前做上一代遊戲機的時候所有會有實時陰影的模型都會做一個低模和專門的材質(如果有透貼陰影的需求)。

對于寫實類型的遊戲,decals的正确制作方法是拿相機去拍,比如地上的水漬,牆上的裂痕,車上的劃痕之類的,開閃光燈拍照,然後回來在ps裡面摳出來。

有很多arpg的遊戲中都有霸體的設計,霸體中不會受擊,其實這個的正确做法是動畫新增一個受擊層,在播放霸體動畫的同時輕微的blend一個受擊動畫,打擊感會舒服很多。

午飯時間!

反響不錯啊,再來一波=)

寫實風格的貼圖,推薦盡量使用Substance制作,打包不同目标平台的時候,可以根據目标平台的實際硬體情況,決定是Bake出Texture還是用Procedual Texture,其實很多時候會發現很多PBR貼圖除了Google圖檔出來修改之外,隻有Substance才能比較好的制作出來。

有一個關于Animation Driven的系統中,AI的制作問題,主要是因為動畫狀态機自己有自己的行為準則,是以傳統的AI設計思路就變得比較無力,比如說我希望我的NPC每0.3秒攻擊一次,但是攻擊動畫本身就超過0.3秒了,怎麼辦?或者說狀态機的邏輯無法響應到0.3秒的攻擊。這個時候需要跟策劃溝通,在Animation Driven的系統下,要完全的分開設計,NPC的大腦是AI,NPC的體格是動畫狀态機,很多時候AI的設計要根據體格的情況來酌情調整。要在行為樹裡增加一些檢查身體體格的節點,比如說,我要轉向某個方向,那麼在适當的時候需要檢查自己的身體是否真的轉到指定方向了;同時對于大腦向身體發送的指令要分優先級,優先級的實作方法是該指令的有效時長,比如說我的身體在受擊的狀态中,但是我的大腦仍然下指令讓我攻擊一次對方,這條指令優先級存在時間0.2秒,如果受擊狀态在0.2秒内複原了,則該指令身體可以執行一次,如果0.2秒内身體仍然無法攻擊,就丢掉此次指令。

Volumetric Cloud/Fog/Light的使用一定要提前和美術進行商量,因為計算過程中牽扯到大量的Depth sampling,是以畫面中多大會存在多大面積的這類效果一定需要嚴格控制,否則到了後期不得不移除這些效果的時候會讓整個産品瞬間降低一個檔次。

在一些中低端裝置上可以用一些簡單的壓縮算法來把RGB + Luminance除以一個除數來壓縮到32bits的顔色空間中來獲得非常劃算的HDR效果,相比較RGBM,用除數可以免費獲得“假”正确的alpha blend效果。這一條無需和美術溝通,直接上就行。(移動平台可用,效果很好)

關于內插補點,內插補點計算最大的問題是需要和策劃溝通清楚,越是符合現實生活運動規則的,隻能使用實體的方法進行內插補點,實體的方法是沒有辦法精确的保障內插補點的最終位置和時間,但是卻可以獲得完美的內插補點效果。這裡有一個非常小的tips來實作實體內插補點:一個物體從旋轉R0,位置P0,內插補點到旋轉R1,位置P1,需要內插補點的時候,在物體上挂一個彈簧,彈簧的另外一端挂在位置P1上,另外物體的運動規則增加兩條:1,每幀運動轉角不能超過XX度;2,物體的實際運動位置是目前朝向 * 力矩;即可,內插補點出來效果棒棒哒,無論是飛個火球還是跟蹤飛彈都可以用這個。

美術資源的優化,這件事情比較好的方法是要嚴格的關注,但是盡量不要過早的修改這些問題,因為開發的過程中始終要留一些空間用來提升畫面效果,是以過早的修改掉性能瓶頸,可能會導緻到最後不得不放棄已經內建進版本的一些效果,非常不劃算。是以等大家都對畫面比較滿意了之後,再進行一輪性能優化,結果還能再增加一些效果,對于美術大兄弟們來說就變成一件很好的事情了。

本來沒打算寫這麼多,隻是開始寫了個頭,就發現還有很多類似的問題也都可以羅列出來,于是出現這麼多雜亂的内容,回頭有時間會仔細整理整理,比如說配個圖什麼的,如果有朋友對于一些tips有疑義或者想知道一些詳細的實作細節,歡迎私信單聊。

應某同學的要求

更新一波手遊的經驗ヽ(•̀ω•́ )ゝ

貼圖進版本的時候做一個alpha通道的剝離,一方面可以比較友善的适配安卓ETC1壓縮格式,另一方面後期要壓包的時候alpha通道可以随意縮大小,美術基本無感覺。

如果是UI資源比較重的遊戲可以采取layout和資源分離的方式來獲得大量的性能提升。針對unity引擎來說就是周遊ui裡所有用到的material,把裡面的貼圖替換成4*4的空白貼圖,另外建立一個從材質對應貼圖的索引。因為手機是ssd的緣故是以磁盤io讀取貼圖的速度是非常快的,這樣就可以把整個ui的layout都留在記憶體中不用切場景釋放,不同場景對應加載不同的貼圖做一個運作時的對應即可,加載ui的時間能提升80%。這一步建議新項目中前期使用,後期項目做這種級别的修改不劃算,風險高。

如果是動畫資源比較重的産品,建議使用自定義的動畫格式,采取float16的四元數儲存關鍵幀資料,然後加載時還原引擎需要的動畫資料,以前做wii上的産品,1000個左右的人形動捕資料可以壓縮到23m左右。

經曆過很多手遊項目的全屏大圖比較多(推廣圖,loading圖),有的會占到整個貼圖量的30%甚至更多,這時候一定要優化大圖的制作工藝,和美術溝通把背景,文字和前景拆開制作,一方面可以更好的壓縮(方形,2的次幂),另一方面背景圖可以采取比較極端的壓縮參數。

加載的過程中往往最後會卡一下,這個是第一次shader送出到gpu産生編譯消耗的時間,可以通過在螢幕上繪制一個透明的三角形來完成warmup,這一步基本上主流引擎都有接口,如果單幀消耗過高,可以考慮分布在若幹幀裡完成。

打擊感的一個小trick,擊中的一瞬間把時間tick調成0持續個0.1秒左右,又輕巧效果又好。

搭建UI架構的時候給每頁ui增加一個fadein和fadeout的接口并且管理好狀态機的切換,今後可以很友善策劃或者美術增加ui打開和關閉的動态效果。

2018國慶更新

國慶期間玩了一些當下比較流行的遊戲産品,感觸還是挺大的,玩法設計都非常的優秀,但是整體的産品的品質差得還是比較遠的,是以這一次我打算更新一期專門講UI開發的套路。

在國産遊戲中,UI是比較重的一塊,基本上一個項目會有70%-80%的開發量都集中在UI上面,那麼有效的提高UI的生産開發效率以及UI的品質,就會讓整個産品無論是成本還是效果上都會提升很大一個檔次。

為每個UI上看得到的控件都封裝一個獨立的類,不要去直接用Button或者AnimationButton這種級别封裝的類,太底層了,至少要封裝到:OKButtonGeneral, CancelButtonGeneral這種級别的類,因為UI往細節上調整無非就是加動畫,加效果,如果不想一個個來搞就從最開始設計UI的時候就先把這些基類建好。

給每個可以互動的控件都要單獨設計一個響應範圍,例如有一個很小的圖檔,很難點中,但是把圖檔放大了又不太好看,是以最好的方式就是用小圖,但是擴大響應範圍。對應的要開發一個開關,讓策劃人員可以随時看到每個控件的響應範圍。

UI開發中比較大的痛點就是每次重構或者換風格的時候,有大量的舊資源搞不清楚是否還在使用,删又不敢删,之前的美術或者策劃或者程式又離職了,這樣整個項目越開發越臃腫,越不可維護,碰到這種情況千萬不要猶豫,在開始換風格的時候就一定要說明,原有的UI Atlas一個都不能重用,全部用新的,因為做一次atlas的時間是你清理一次資源的1/10的時間和精力,資源的版本管理本來就是技術分内的事情。

給每一頁UI取一個有意義的名字,我就見過好幾個美術策劃程式為一個UI問題争吵了很長時間,最後發現大家在讨論的是不同的東西,UI的命名一定不能重名,否則到了後期,哪個UI在用,從哪邊跳轉過來的都分不清,文檔都沒法寫。

UI的跳轉,不要簡單的切換一下頁面,把之前的隐藏,新的顯示出來這樣。一定是先push一個切換UI的請求,然後UI控制中心要根據目前UI的動畫播放情況,邏輯是否處理完了等等來決定是否切換,而且切換隻是把目前頁面指向棧頂元素,因為還要通過pop來處理傳回的邏輯。

我以前看過一個程式小朋友開發UI,發現他工作中有接近30%-40%的時間是在處理顯示層級的問題,即誰顯示在誰前面。這裡分享一個小技巧,如果你無法想明白究竟誰應該在前,誰應該在後,那就說明這兩個東西本身就應該是同一個東西,寫一個新的類來包含這兩者,比如說有個ITEM的圖示,圖示上面要畫一個高亮選擇光圈,光圈上面還要顯示ITEM的數量,那麼說明這三者就應該放到一個統一的類裡面去,例如說GlowableCountableItems

UI裡面除了圖檔之外,其他的控件都應該采用九宮格,或者反過來說,隻有碰到你沒有辦法采用九宮格的元素,才考慮不使用九宮格。

做螢幕适配的時候,不要考慮縮放圖檔這樣的方法,按照九宮格的原理進行挂靠,如果内容太多,就需要考慮在細節元素上面再挂一個父節點,通過挂靠父節點來完成适配

字型不要亂用,一般一款遊戲控制在3種字型以内,不要輕易的給字型加類似粗體/斜體之類的效果,因為最終字型是要畫到貼圖上緩存起來的。用到專門的字型一定要購買一個版權,省的上線以後打官司。

UI的本地化問題遵循的原則是開發一個類似于LocalizableText之類的控件,裡面輸入什麼文字自動的寫到資料庫裡,否則到了後期UI量大了要把文字提取出來都不是件容易的事。

另外一個本地化相關的就是美術字也應該做成特殊的資源,類似LocalizablePictureText這樣的,也是節約後期本地化的時間。這些統稱為LocKit(Localization Kit的簡稱)有了這些基礎設施,之後無論是産品出海到哪個國家都可以比較安心,不慌。

有一些UI效果可以考慮用shader來完成,舉個例子,類傳奇的遊戲裝備圖示都會有一圈光圈圍着轉,這個東西用shader可能就是10行之内的事,我看到過最奇葩的實作方法就是建立了10多個小珠子,每一幀計算這10多個小珠子的位置來實作,當時我就驚呆了。

輸入法這個東西要謹慎處理,如果是單機遊戲,都可以考慮在彈出輸入法的時候讓遊戲暫停,因為你在輸入的時候其實是沒有辦法和遊戲進行其他互動的。

很多遊戲都有某個視窗彈出來的時候,背景模糊掉之類的需求,這種的正确制作方法是實作一個類叫BackBufferPicture,然後這個類可以配置截圖的參數和屬性,這樣在任何地方都可以很友善的來實作這樣的效果。

同樣也有很多需求是在UI中嵌入3D模型,這個也是要實作一個獨立的類來實作,如果3D模型上還要增加一些UI來對3D模型進行一些說明,則應當用HUD的方式在3D中實作。另外UI中嵌入3D模型很多程式直接用正交投影,這樣出來的效果就會比較奇怪,但是一時又說不上來,記住,任何情況下顯示3D物體都請用透視投影。

釋放UI的時候一定要記得釋放Render To Texture的記憶體,現在動不動就是2K螢幕,一塊FrameBuffer很耗記憶體的。

歡迎大家關注公衆号“創小董”我會繼續分享更多更真實的創業經曆、經驗、解決辦法。

繼續閱讀