發表文章

URP 的影子為什麼模糊? Sphere Fit、Tight Fit 與高度切片的差異

圖片
遊戲當中的陰影,時常面臨鋸齒的困擾。最直接的做法是提高 Shadow Map 的尺寸,但這會大幅增加記憶體開銷。因此,如何在有限的解析度下「更有效率地利用 Shadow Map」,就成了關鍵。 斜視角遊戲常見的問題:角色靠近相機時,影子邊緣有明顯的鋸齒,甚至出現縫隙。原因不在貼圖解析度不夠,而在於 貼圖涵蓋了太大的世界範圍 。 這邊從 Shadow Map 的原理講起,再比較三種把 Shadow Map 對準畫面的做法: Sphere Fit 、 Tight Fit ,以及加上 高度切片 的 Tight Fit 。 影子是怎麼畫出來的 即時影子用的是 Shadow Map:先從光源視角渲染一張深度貼圖,再讓每個像素和它比較,判斷是否被擋住。貼圖解析度固定(例如 2048×2048),涵蓋的範圍越大,每個像素(texel)對應的面積就越大,邊緣就越粗糙。 為了讓近處更精細,常把視錐沿深度切成幾段(Cascade),每段各做一張貼圖。每一段要決定光源用多大的正交投影框去涵蓋它,這一步叫 擬合(fit) 。框越貼近真正需要的範圍,貼圖就越不浪費。 三種擬合方式 下圖是側視示意:相機斜著往下看,藍色梯形是視錐的一段切片,切到地面以下的部分是灰色。彩色斜帶是 Shadow Map 涵蓋的範圍(沿著光線方向延伸)。 Sphere Fit Tight Fit Tight Fit + 高度切片 涵蓋寬度 100% 涵蓋寬度 約 84% 涵蓋寬度 約 59% 示意圖。圖中的寬度比例是由圖面座標算出,不是引擎的實測數字。 1. Sphere Fit(Unity URP 預設) 用一顆球把這一段視錐切片整個包起來,再以球的直徑當作投影框的邊長。 優點: 球的大小不會隨相機旋轉改變,所以 Shadow Map 非常穩定,轉動相機時影子邊緣不會閃爍。 缺點: 球一定比視錐切片大,多出來的範圍都在浪費貼圖。 2. Tight Fit 把切片的 8 個角點轉到光源空間,取最小的軸向包圍盒(AABB)當投影框。 優點: 範圍比球小,同一張貼圖的 texel 更密,影子更清楚。 缺點: 包圍盒的大小會隨相機旋轉而變,所以旋轉時陰影邊緣可能輕微爬動。平移相機時,把框對齊 texel 格線就能保持穩定,旋轉時則無法完全消除。另外,圖中灰色的地面以下部分、以及天空,仍然在涵蓋範圍內。 3. Tight F...

URP 14 升級 。RenderTargetHandle 改 RTHandle 與 API 變動

圖片
最近在 URP管線 (Universal Render Pipeline) 下想實現一些以往的效果。打開新專案之後才發現,舊的作法已經需要調整。 經由一查之下才知道,原來 URP的 API 有做了一些調整。 像是 :  原本的 RenderTargetHandle 相關功能,需要改成 RTHandle 。 RTHandle 可以配合 URP管線當中的 Shader  Tags 製作需要的相關的 屏幕遮罩 。  以及在 public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 底下的 context.DrawRenderers 的功能需要改成 cmd.DrawRendererList(context.CreateRendererList(ref rendererListParams)); 等等的調整。 詳細的變動可以觀看官方的說明 https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@14.0/manual/upgrade-guide-2022-2.html

Rain Drop

圖片
  下雨效果分析,可以分成2個部分。一個是平面的雨滴效果,一個是垂直側面的流水效果。 先來看平面的雨滴效果。可以用類似積雪的方式,找出模型法線向上的部分,再搭配下雨的序列圖,組合出水平面的雨滴效果。 再來是垂直側面的部分。跟垂直類似,遮罩採用模型法線X與Z方向的遮罩,配合擾動UV流動的效果製作側邊的流水效果。 最後再將效果合入shader當中PBR的光照計算即可。 References: https://www.youtube.com/watch?v=9JkG-orTQO8

Unity Shader 地平線彎曲效果

圖片
  這次來實現一下地平線彎曲的效果。有看過 Switch 的<動物森友會>的應該都有看過場景的遠景地方會彎曲的效果。 要實現的方式可以從 Shader vertex 上做頂點的彎曲。詳細的做法可以參考 HORIZON BEND 的 PDF 文章。 這邊就簡要的放上核心的曲面部分,基本上就是先將模型轉換為世界座標,再去製作彎曲效果,最後再轉回模型的本地座標。 如此一來就可以達到模型彎曲的效果。由於是在vertex製作彎曲,因此模型的面數也是會影響到彎曲後的效果。  最後就是讓地板循環位移,可以達到攝影機跟人物不動,而視覺有前進的效果。 References: https://battlehub.net/HorizonBend/HB.pdf https://unity-chan.com/download/releaseNote.php?id=SDUnityChan&lang=en

TextmeshPro-Gradient

圖片
這次來寫一篇關於 TextmeshPro 的擴展應用。有用文字系統的夥伴,相信一定對於 TextmeshPro 不陌生。由於它的多樣性文字效果,使得他幾乎專案當中是必備的存在。 然而 TextmeshPro 默認的漸層模式卻也是稍有侷限,只能接受上下 2種 不同得顏色的漸變效果,有時候不見得能夠符合需求。 因此這次則對漸層的方面做出擴展,來讓 TextmeshPro 能更支援更多的顏色漸變。 從默認的漸變模式的Shader可以得知,由於默認的漸變是藉由 頂點色染色 的緣故,因此對於一片面來說只有4個頂點,所以最多只能做到 上下 或是 左右 的漸變變化。 對此則可以運用給予漸層貼圖的方式讓它的漸變能支援更多的顏色變化。以下是使用 Gradient 動態產生建成貼圖。 Texture2D GenerateTextureFromGradient (Gradient gradient, int width = 64, int height =1 ) {             Texture2D texture = new Texture2D(width, height, TextureFormat.RGBA32, false);             for (int y = 0; y < height; y++)                 {                 for (int x = 0; x < width; x++)                     {                     float t = (float)x / (width - 1);         ...

Stencil Portal Effect

圖片
前些日子有個需要傳送門的效果,這裡就寫一下  Stencil 的功能。 從官網的解釋 : 模板緩衝區為幀緩衝區中的每個像素儲存一個 8 位元整數值。在為給定像素執行片元著色器之前,GPU 可以將模板緩衝區中的當前值與給定參考值進行比較。這稱為模板測試。如果模板測試通過,則 GPU 會執行深度測試。如果模板測試失敗,則 GPU 會跳過對該像素的其餘處理。這意味著可以使用模板緩衝區作為遮罩來告知 GPU 要繪製的像素以及要丟棄的像素。 大致上有個了解。就是將 ref 中的 value 與 buffer 中的 value 進行比較,來決定繪製像素的一種方式。 主要的配合方式可以如下 :  如此便可以製作出物件通過 傳送門 的效果。 附帶一提,Stencil 也可以用在 人物遮擋 的顯示效果上面。 References: https://docs.unity3d.com/cn/current/Manual/SL-Stencil.html https://www.youtube.com/watch?v=toQIuCtk2pI https://www.youtube.com/watch?v=SySnHIhiVgM

Unity Overdraw 是什麼?手機遊戲效能優化與檢測

圖片
  這次來看一下有關性 能方面的大殺手 Overdraw 。 相信許多特效的夥伴對這名詞一定不陌生。 Overdraw可以解釋為,在一幀中, 同一個像素的多次(重複)的繪製 。而畫面當中大量的 Overdraw 則是手機/移動平台上的性能大忌。會很嚴重的影響到 FPS 。 目前市面上的 手機/移動平台是 採用 TBR(tile-based rendering) 的渲染方式,因此在 CPU 到 GPU 之間需要傳輸大量的數據,而大量的 Overdraw 則會導致 頻寬消耗 ,造成渲染性能(FPS)下降。 再來從渲染管線來看,手機/移動平台的渲染管線大都是 Forward Rander (向前渲染) 的原因,因此容易造成大量 Overdraw 的因素大部分會產生在 Transparent 跟 UI 層級 以及 P ost Processing (後處理) 上面。 而為了避免 Overdraw 造成的性能浪費,在素材製作上製作也必須有些基本的概念。 1. 特效 的效果則有很大部分都會藉由粒子系統的效果產生大量的 Mesh,從而導致大量的疊加情況。需要限制噴發模型數量,來減少疊加的狀況。 2. UI 的製作上也避免過多的層級疊加。 3.P ost Processing (後處理) 避免使用過多的後處理。由於每一種後處理都是全屏幕的像素繪製。 最後性能檢測方面。我們可以用最值觀的 引擎內的 Overdraw 模式 來檢視。或是可以用 Render doc 來進行更仔細的幀 畫面分析。 Render doc 單場景大量粒子疊加Overdraw畫面 或是可以用 OverdrawMonitor 工具來觀察畫面 的 Overdraw 比例 。原則上再依畫面盡量能保持在 3.0 以內為最好。(1.0 即是每一項像素只繪製一次) References: https://zhuanlan.zhihu.com/p/350778355 https://www.youtube.com/watch?v=vJZcbscZ4-o https://github.com/Nordeus/Unite2017/tree/master/OverdrawMonitor