標籤:

從零開始手敲次世代遊戲引擎(三十二)

差不多是時候將我們前面所寫的場景管理模塊與圖形渲染模塊結合起來了。

首先我們使用DDC工具創建並導出一個場景。這裡我們以開源(免費)的Blender作為演示。Blender的下載地址在參考引用*1當中。

另外因為目前我們只實現了OpenGEX的導入,我們需要下載一個Blender用的OpenGEX導出腳本(插件)。下載地址在參考引用*2當中。

簡便起見我們就導出Blender的預設場景,具體步驟參考下面的錄屏:

https://www.zhihu.com/video/917141302787842048

接下來我們需要修改RHI/OpenGL/OpenGLGraphicsManager.cpp,主要需要修改InitializeBuffers,將原來Hard coding在其中的頂點數據去除,改為從Framework/Common/SceneManager當中動態獲取。

修改Test/SceneLoaderTest.cpp,將其中讀取的文件從「Example.ogex」改為我們剛剛導出的「cube.ogex」,編譯執行,觀察格式能夠被識別並且能夠正確導入。

導入的頂點數據包括兩個屬性:position和normal。也就是說有頂點的坐標,還有頂點處的法線,但是沒有頂點色。我們之前寫的color.vs和color.ps是需要頂點坐標和頂點色,這裡需要改一下。將Asset/Shader下面的color.vs和color.ps各自複製一份,重新命名為basic.vs和basic.ps,並且將其中的頂點色部分替換為頂點法線,或者去除。

////////////////////////////////////////////////////////////////////////////////n// Filename: basic.vsn////////////////////////////////////////////////////////////////////////////////nn#version 150nn/////////////////////n// INPUT VARIABLES //n/////////////////////nin vec3 inputPosition;nin vec3 inputNormal;nn//////////////////////n// OUTPUT VARIABLES //n//////////////////////nout vec4 normal;nn///////////////////////n// UNIFORM VARIABLES //n///////////////////////nuniform mat4 worldMatrix;nuniform mat4 viewMatrix;nuniform mat4 projectionMatrix;nn////////////////////////////////////////////////////////////////////////////////n// Vertex Shadern////////////////////////////////////////////////////////////////////////////////nvoid main(void)n{n // Calculate the position of the vertex against the world, view, and projection matrices.n gl_Position = worldMatrix * vec4(inputPosition, 1.0f);n gl_Position = viewMatrix * gl_Position;n gl_Position = projectionMatrix * gl_Position;nn normal = worldMatrix * vec4(inputNormal, 0.0f);n normal = viewMatrix * normal;n}nn////////////////////////////////////////////////////////////////////////////////n// Filename: basic.psn////////////////////////////////////////////////////////////////////////////////n#version 150nnn/////////////////////n// INPUT VARIABLES //n/////////////////////nin vec4 normal;nnn//////////////////////n// OUTPUT VARIABLES //n//////////////////////nout vec4 outputColor;nnn////////////////////////////////////////////////////////////////////////////////n// Pixel Shadern////////////////////////////////////////////////////////////////////////////////nvoid main(void)n{n outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);n}n

簡單起見我們還未考慮光源。本來在PS Shader(fragment shader)當中應該根據法線和光源的夾角進行光照計算的,現在我們暫時固定輸出白色。

修改Framework/Common/main.cpp,讓SceneManager載入cube.ogex。編譯執行之後的顯示如下:

https://www.zhihu.com/video/917149422624862208

為了確認這個立方體確實是從外部導入的,從Blender場景當中刪除立方體,新建一個Monkey,然後重新導出,覆蓋cube.ogex。然後重新執行程序,顯示如下:

https://www.zhihu.com/video/917151670545301504

下一步,嘗試在Blender當中加入多個幾何體,然後導出,用我們的程序導入並渲染:

https://www.zhihu.com/video/917492700981391360

https://www.zhihu.com/video/917491658235482112

這裡我們會發現雖然我們在Blender裡面將幾何體都在位置上錯開了,但是渲染的結果是重疊在一起的。這是因為我們目前只是簡單地從SceneManager獲取SceneObject(場景物體)進行渲染,而沒有根據SceneNode(場景圖)進行場景物體的擺放(場景位置計算)。這是我們接下來的工作。

另外,如果仔細觀察,會發現我們的幾何體邊緣有明顯的鋸齒。這些鋸齒是由於採樣精度產生的。改善這些鋸齒的演算法被稱為反走樣技術(Anti-Aliasing,簡稱AA)。AA有很多衍生的演算法種類,但總的來說大都是在一定範圍內採用提高採樣精度的方式來解決的。其中比較廣泛使用的,效果也比較理想的,並且得到圖形硬體支持的技術之一,MSAA,是可以通過在創建圖形context(FrameBuffer)的時候指定特定的選項來打開的。

參考引用*3當中詳細解釋了在Windows/Linux/macOS這三種主流平台用OpenGL打開MSAA的方法。但是macOS當中使用Cocoa的方法尚未記述。通過類比並綜合網上其它的信息,最終確認在macOS上使用Cocoa打開MSAA的方法如下:

int CocoaOpenGLApplication::Initialize()n{n int result = 0;nn result = CocoaApplication::Initialize();nn if (!result) {n NSOpenGLPixelFormatAttribute attrs[] = {n NSOpenGLPFAAccelerated,n NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,n NSOpenGLPFAColorSize,32,n NSOpenGLPFADepthSize,24,n NSOpenGLPFAStencilSize,8,n NSOpenGLPFADoubleBuffer,n NSOpenGLPFAAccelerated,n NSOpenGLPFAMultisample,n NSOpenGLPFASampleBuffers,1, // 4x MSAAn NSOpenGLPFASamples,4, // 4x MSAAn 0n };n

打開之後的效果如下:

https://www.zhihu.com/video/917496452337532928

最終代碼在article_32的分支當中。

本作品採用知識共享署名 4.0 國際許可協議進行許可。

參考引用

  1. blender.org - Home of the Blender project - Free and Open 3D Creation Software
  2. opengex.org/OpenGex-Ble
  3. khronos.org/opengl/wiki

推薦閱讀:

從零開始手敲次世代遊戲引擎(七)
在奇葩的 Json 世界裡冒險! - 《沒有勇者的世界》開發日誌 (2)
從零開始手敲次世代遊戲引擎(三十六)
從零開始手敲次世代遊戲引擎(二十六)
陳灼:我在2K的八年(序)

TAG:游戏开发 |