Hello,大家好這次帶來第二篇遊戲的逆向,嗯這次是業餘抽空的時間做的一個關於歐陸風雲4的地形系統的逆向,做這個的原因呢是因為非常喜歡P社的遊戲和設定,其次是想在這個的基礎上,做一個關於門派經營和養成的策略遊戲,可以參考(天下霸圖),其基本設定大致想分為三個部分去做,一個是大地圖的勢力劃分(參考P社5萌),第二是門派建設和人物養成部分,可以參考開羅系列,最後的戰鬥系統容我做出來了再介紹給大家。現在的進度是正在進行第二部分的開發- -,這次的逆向是對歐陸風雲的整個地形和填色系統的簡單總結,希望能夠在某個方面幫助到大家。

首先,關於地形系統的基本原理,可以參考各種渲染的入門書籍,比如Introduction to 3D Game Programming with DirectX 11。其中有專門的章節關於地形系統的基礎入門,其基本原理都是通過使用一張高度圖,來描述地形的高度的差異。再通過這場高度圖,在CPU側生成對應的Mesh網格,或者使用曲面細分,或者LOD的方式,在GPU來採樣高度圖實現。我們這次的實現是採用CPU側的方式。接下來的文章大致描述以下幾個部分:

1.地形Mesh的生成

首先我們需要一個類似地球的大世界地圖的網路生成,來作為我們地形渲染的基礎,我們的目標就是研究如何生成一個高精度的地形Mesh,以及討論歐陸風雲4的做法。

2.地形的渲染

在擁有了地形的Mesh之後,我們第二步要做的就是,渲染出和歐陸風雲4類似的地形效果,這部分主要是參考歐陸風雲4的原始shader,以及研究歐陸風雲4是如何做到渲染一張至少效果還不差的(偽高精度)地形。

3.水面和河流

在擁有了基本的地形之後,我們還需要實現對應的水面和河流效果,這部分的效果也是參考歐陸風雲4的原始代碼, 問題是關於河流的程序生成,我們也繼續討論一下歐陸風雲4本身是如何做到可擴展和可Mod的。

4.省份填色

第4部分呢,我們討論一個比較難一點的話題,就是如何染色,以及如何高效率的染色。畢竟學習地理就靠這個遊戲了。- -

5.迷霧

最後呢,我們完成最後的一個步驟,那就是戰爭迷霧的實現。

總的來說,歐陸風雲4的地形系統還是做得很好的,兼顧了效率- - (一核有難,那個*核圍觀),並且我們可以通過逆向的過程學習到一些基本的渲染效果的實現方法。

1.地形Mesh的生成

我們使用一張高度圖來生成我們的大地圖的Mesh,可以通過一張圖來反映其基本思路

地形實現思路

首先構造出一個由非常多小面片組成的平面mesh,這個mesh片是平整的(1),所以是沒有高度區分和凹凸的。 然後對面片上的每個頂點的(x,z)值作為一個紋理坐標, 去高度圖上採樣對應的高度,用採樣的高度來修正mesh片上的每個頂點的y值,就得到了一個擁有基本高度變化的mesh片。其基本代碼如下:

float GetHeight( int x, int z)
{
x %= kHeightMap.width;
z %= kHeightMap.height;

return kHeightMap.GetPixel(x, z).a;
}

int x = (int)pos.x;
int z = (int)pos.z;
float y = GetHeight(x, z) * ConfigParam.BLOCKHEIGHT;

其中kHeightMap是高度圖, 取a通道是因為貼圖只使用a通道來代表高度。

ConfigParam.BLOCKHEIGHT是高度為1.0的地形在世界坐標小的高度縮放,即在高度貼圖高度為1.0的頂點應該位於世界坐標下的高度。

歐陸風雲4使用的高度圖如下:

高度圖:解析度5632*2048

而高度圖的解析度通常是(m* 2^k +1) * ( n * 2^k +1 ) , 其中 m,n 分別是行塊和列塊的數量(每行的塊數, 每列的塊數), k是一個塊的大小。

m=3, n=2 , k=3

那麼為什麼歐陸風雲4的高度圖是 5632 * 2048呢? 答案就是地球是圓的,即地圖的最左邊緣應該和最右邊緣描述的是同一個頂點, 最上邊緣和最下邊緣的頂點描述的點也應該是同一個點,但是歐陸風雲4的地形高度圖實際上只滿足了左右邊緣的一致性,並沒有考慮地球的最北極和南極的情況,這和實際遊戲的體驗也是一致的,遊戲實際上可以無限左右移動,即左右邊緣是滿足了連通的性質的,但是北邊和南邊就只通過一個額外的地圖遮罩處理了。


推薦閱讀:
相關文章