1. 程式人生 > 實用技巧 >高真實感複雜光照環境場景模擬——軟體系統設計方案

高真實感複雜光照環境場景模擬——軟體系統設計方案

1. 軟體系統設計方案

1.1 軟體結構特點

遊戲裡的 "MVC" 架構

遊戲專案裡的也有類似 MVC 的架構。如下圖所示:

把遊戲的架構分成三層:

- Game Application Layer

    - Devices: Input, Files, RAM, Time
    - OS: Language, DLL, Threads, Network
    - Game Life: Core Libs, Main Loop, Init & Shutdown

- Game Logic

    - Game State & Data Structure
    - Physics
    - Events
    - Process Manager Common Interpreter

- Game View(s)

    - Process Manager
    - Options
    - only for Human
        - Display: 3D Scene, UI, Video
        - Audio: SFX, Music, Speech
        - Input Interpreter
    - only for AI Agent
        - Stimulaus Interpreter
        - Decision System

其中游戲邏輯的輸出可能是 AI ,也可能是真實的玩家。所以要對應不同的檢視。

而本專案依賴的專案是 Unreal Engine,一個巨大的遊戲引擎。這個工程實際關注在渲染模組。渲染模組一個
重要的設計考量是抽象各個平臺的驅動介面。比如 D3D, OpenGL, Vulkan 等。這就意味著,設計必須要能夠
根據平臺來切換渲染介面。這還是有 “切換檢視” 的概念應用。

依賴檢視

依賴檢視展現了軟體模組之間的依賴關係。比如一個軟體模組A呼叫了另一個軟體模組B,那麼我們說軟體模組A直
接依賴軟體模組B。如果一個軟體模組依賴另一個軟體模組產生的資料,那麼這兩個軟體模組也具有一定的依賴關
系。依賴檢視在專案計劃中有比較典型的應用。比如它能幫助我們找到沒有依賴關係的軟體模組或子系統,以便獨
立開發和測試,同時進一步根據依賴關係確定開發和測試軟體模組的先後次序。依賴檢視在專案的變更和維護中也
很有價值。比如它能有效幫助我們理清一個軟體模組的變更對其他軟體模組帶來影響範圍。

Renderer 依賴 Engine 和 RenderCore 模組。
Engine 只依賴於 RenderCore。
RenderCore 不依賴他倆。

本專案要拓展實現的模組在 Renderer 裡。

泛化檢視

泛化檢視展現了軟體模組之間的一般化或具體化的關係,典型的例子就是面向物件分析和設計方法中類之間的繼承
關係。值得注意的是,採用物件組合替代繼承關係,並不會改變類之間的泛化特徵。因此泛化是指軟體模組之間的一
般化或具體化的關係,不能侷限於繼承概念的應用。
泛化檢視有助於描述軟體的抽象層次,從而便於軟體的擴充套件和維護。比如通過物件組合或繼承很容易形成新的軟體
模組與原有的軟體架構相容。

Unreal 中的渲染器類都繼承自 FSceneRenderer。分為移動渲染器和延遲渲染器。本次要實現的程式碼在移動
渲染器中,但要參考到延遲渲染器的實現。

實現檢視

實現檢視是描述軟體架構與原始檔之間的對映關係。比如軟體架構的靜態結構以包圖或設計類圖的方式來描述,
但是這些包和類都是在哪些目錄的哪些原始檔中具體實現的呢?一般我們通過目錄和原始檔的命名來對應軟體架構
中的包、類等靜態結構單元,這樣典型的實現檢視就可以由軟體專案的原始檔目錄樹來呈現。
實現檢視有助於碼農在海量原始碼檔案中找到具體的某個軟體單元的實現。實現檢視與軟體架構的靜態結構之間映
射關係越是對應的一致性高,越有利於軟體的維護,因此實現檢視是一種非常關鍵的架構檢視。

右邊的目錄結構即實現檢視。

1.2 介面API

Unreal 引擎的程式碼非常龐大。我關注的介面在 Engine/Source/Runtime/Renderer/Private
目錄下。其中包含了渲染器的 API。


    SceneRendering.h (FSceneRenderer, FMobileSceneRender)
    SceneRendering.cpp

    MobileShadingRenderer.cpp

    DeferredShadingRenderer.h (DeferredShadingSceneRenderer)
    DeferredShadingRenderer.cpp

移動渲染器 MobileShadingRenderer 和延遲渲染器 DeferredShadingRenderer 都
公有繼承自 FSceneRenderer


class DeferredShadingRenderer : public FSceneRenderer
class MobileShadingRenderer : public FSceneRenderer

父類 FSceneRenderer 裡有一個純虛擬函式 Render 即子類必須實現的渲染入口


virtual void Render(FRHICommandListImmediate& RHICmdList) = 0;

2. 核心資料結構設計

延遲渲染涉及到核心資料即 G-Buffer 裡存的資料,這根據實現的要求所有不同,不過至少會包括:

  • 法向量
  • 各種光照係數:漫反射、高光等
  • 位置向量

還有其他計算的時候涉及的:

  • 光源的資訊
    • 光源型別:
      • 點光源:光向各個方向發散,根據距離衰減。影響範圍是一個球體。
      • 聚光源:光向某個方向發散,根據與此方向的角度衰減,影響範圍是一個錐體。
      • 平行光:光向各個方向發散,且只定義光源的方向,不定義光源的位置(無窮遠的點光源)。
    • 光的顏色
    • 衰減係數
    • ...

3. 軟體系統執行環境和技術選型說明

3.1 執行環境

專案開始時 Unreal Engine 的版本是 4.25,其執行的環境要求是:

推薦硬體

作業系統 Windows 10 64位

處理器 Intel四核處理器或AMD,2.5 GHz或更快

儲存器 8 GB RAM

顯示卡/DirectX版本 DirectX 11或12 相容顯示卡

用引擎開發

'執行引擎' 的所有要求項(自動安裝)

Visual Studio版本

Visual Studio 2017 v15.6或以上(推薦)

Visual Studio 2019

效能說明

本列表列出了Epic採用的常用配置,使用虛幻引擎4的遊戲開發者可以此為參考:

64位Windows 10系統

64 GB RAM

256 GB SSD(系統盤)

2 TB SSD(資料盤)

NVIDIA GeForce GTX 970

Xoreax Incredibuild(開發工具包)

Xeon六核E5-2643 @ 3.4GHz

3.2 第三方庫

ADO
AMD/AMD_AGS
ANGLE
Android
...
DotNetZip
...
rpclib
xxhash
zlib

詳情參見:

https://github.com/EpicGames/UnrealEngine/tree/release/Engine/Source/ThirdParty

4. 系統概念原型的核心工作機制

上次作業的分析中,我說專案的概念原型其實就是:

我們用圖形API編寫的程式,接受由應用程式傳遞的渲染資料,向驅動提交渲染命令。
所謂延遲渲染與傳統渲染的區別,從這個概念原型的層次來看,就是——得到一次渲染結果,
要經過多遍渲染過程。

這次加上了實際應用 Unreal Engine API 後,系統概念原型的核心工作機制可以更具體地描述,
延遲渲染的工作流程:

  • 步驟 1:渲染所有的場景幾何資訊到 g-buffer。一般是把每個畫素對應的材質、表面資訊渲染到 render target textures 裡去。
  • 步驟 2:對光源所影響到的幾何範圍內覆蓋的畫素,進行光照計算,期間從 g-buffer 裡取樣計算所需的資訊。

當然,這些流程都是寫在 Unreal Engine 具體的渲染器類裡的。

參考引用

[1] Software Engineering: Theory and Practice (Fourth Edition),Shari Lawrence Pfleeger,Joanne M. Atlee
[2] http://c.biancheng.net/design_pattern/
[3] https://gitee.com/mengning997/se/blob/master/ppt/軟體科學基礎概論.pptx