[閱讀筆記] Unity shader 入門精要 #5

《Unity shader 入門精要》的讀書筆記,十六章到十九章。 十六章說明渲染上的優化方向;十七章簡單說明了 surface shader;十八章簡單說明了 PBS 技術。 十九、二十章說明一些 Unity  的更新,以及精進渲染技術知識的方向。

第十六章:Unity 的渲染優化

  • 一開始就把優化當作設計的一部份
  • 造成遊戲瓶頸的可能原因:
    • CPU - 過多的腳本運算或物理模擬
    • CPU - 過多的 draw call
    • GPU - 過多的頂點、逐頂點運算
    • GPU - 過多的 fragment、overdraw
    • 解析度過高的貼圖、frame buffer
  • 優化方向:
    • 減少 draw call
    • 優化模型、使用 LOD、Occlusion Culling
    • 控制繪圖順序
    • 注意透明物體的使用
    • 減少即時光照
    • 減少 overdraw
    • 壓縮貼圖大小
  • 使用動態 batching 減少 draw call:
    • 使用同一個材質,Unity 會自動實現動態 batching
    • 一次動態 batching 所能接受的頂點數上限為 900
    • 多 Pass 的 shader 無法動態 batching
  • 使用靜態 batching 減少 draw call:
    • 將物體設定的 static 打勾
    • 在程式運作一開始,將數個模型合併
    • 會占用更多記憶體
    • 物體不可被移動
  • 共用材質的技巧
    • 合併貼圖
    • 將相異的 shader 參數儲存於頂點顏色 (或其他頂點數據)
    • 使用 Render.sharedMaterial
  • 減少 overdraw 技巧:
    • 對於確定會在最前方的物體,調整其渲染順序往前
    • 減少透明的使用
    • 在移動裝置上,因為 GPU 架構的差異,透明度混和可能會優於透明度測試
    • 使用 lightmap 代替即時光照,移動設備上甚至要避免使用逐像素光照
  • shader 程式碼優化
    • 用 float 儲存頂點座標,用 half 儲存 uv 座標,用 fixed 儲存單位向量
    • 避免變數精度轉換
    • 盡量合併差值計算
    • 盡量避免 if、loop 語法
    • 盡量避免三角函數跟指數運算
    • 盡量避免 discard,這跟一些 GPU 的優化架構有關
    • 一些細節會因平台而異

第十七章: surface shader

  • surface shader 是 unity 對於 shader 的進一步抽象封裝
    • https://docs.unity3d.com/Manual/SL-SurfaceShaders.html
    • 在 SubShader 中編寫而非 Pass
    • 方便撰寫但能夠實現的自定義渲染較有限
    • 性能較差,但如果需要處理許多光照,是個好的選擇
    • 如果光照單純,使用 vertex/fragment shader 效能會好很多
  • 編譯指令 #pragma surface 用於定義使用的函數及光照模型
  • 函數格式:
    • void surf (Input IN, inout SurfaceOutput o)
    • void surf (Input IN, inout SurfaceOutputStanderd o)
    • void surf (Input IN, inout SurfaceOutputStanderdSpecular o)
    • Input 結構有一些內建的變數、也可自訂增加變數
  • 光照模型:
  • 其他參數:
    • vertex 修改頂點的函數
    • finalcolor 在顏色存入 frame buffer 前進行修改的函數
    • adddhadow、fullforwardshadows、noshadow
    • alpha、alphatest
    • exclude_path 可以在移除對特定的渲染路徑的支援

第十八章:Physically Based Shading,PBS

  • 基於物理的渲染 Physically Based Shading
    • 比起 Lambert,使用了考慮細微漫射及次表面散射的 BRDF 等式
    • Standard 跟 Standard Specular 使用相同的 BRDF 等式,只是對外調整的參數項目及意義不同,依然可以做出相同的表現
    • 使用 HDR 的 skybox 可以表現出更真實的光照,擁有更高的亮度精度,但是運算需求也較高
  • Unity 5 的 Global Illumination (GI) 可以提供間接光照,增加光照的真實感,可由光源的 Bounce Intensity 調整間接光照的強度
  • 平行光的 Baked 模式會將場景光照儲存到一張 lightmap,Mix 模式則只儲存 static 物件的光罩,剩餘物件採用即時渲染
  • 反射探針 (Reflection Probes) 的設置,可以提供反射所需的 cubemap
  • Gamma space 與 Linear space 的顏色差別:
    • Linear space 較接近真實的顏色
    • 一般紋理貼圖是以 Gamma space 儲存,如果硬體支援,Unity 會自動進行顏色空間的轉換
    • 如果硬體不支援,可以在 shader 中以效能為代價進行手動轉換