2018-02-18

【進度】3D背景實裝過程

這是筆者與3D美術人員,還有兩位看板娘的研究筆記,從不懂開始一步步做到實用化,摸清楚遊戲中的3D要注意的地方。
鈷寶:……,咦,什麼?要出場?
艾莉兒:主人,我們好像有好幾個月沒出場了。
抱歉,前陣子做的事剛好都想不到怎麼寫你們的對話。

模型檔格式我採用PMD(MikuMikuDance的模型檔),因為它的構造幾乎就是依照D3D和OpenGL函式的需求,容易解析,也很容易想像用什麼流程render、shader要怎麼寫。(PMX比較複雜,暫不考慮)
然後有專門的編輯工具PMDEditor和PMXEditor,Blender也有外掛可存取PMD檔。

想說通用的格式有現成的工具可用,比較省事,結果又是重重難關……。
同時發在巴哈姆特



給美術的規格書裡有寫要用的檔案格式是PMD,只是要如何輸出PMD檔我並沒有給他工具,讓他自己想辦法,結果美術給我的是Wavefront obj檔。

如「【製作進度】3D技術研究1-引擎本體」所說,當時已經讓艾莉兒有處理3D的能力,只要再做一些跟遊戲整合的部分。

鈷寶,tilemap編輯器要增加8195號事件,有x,y兩個參數,要把它輸出到事件列表裡。
鈷寶:嗯……。
艾莉兒,幫你新增一個圖像物件:3D模型,還有讀到8195號事件就表示要設背景位置,參數的作用是……
艾莉兒:好,了解!

模型轉檔是先安裝存取PMD的外掛,用Blender讀取obj檔→輸出成PMD檔,再給艾莉兒用,暫時還不用鈷寶動手。

艾莉兒:上吧,第一個版本!
(此時貼圖還沒畫好)


美術看過後發現一個問題,原本應該是平面的地方遊戲裡看起來有弧度,稜角也是圓的而沒有角的感覺。
檢查後發現是Blender載入obj的功能有問題,不能讀取頂點的法線,之後再輸出PMD法線就錯了。

艾莉兒:我查查看……,這裡說它不會讀obj裡的法線資料,是它自己重新產生的,可惡,Blender竟然有這個bug!
Blender說明文件,關於讀取obj檔

詳細情況是,obj裡的資料是這樣
#頂點位置
v 155.0000 0.0000 0.0000
v 155.0000 0.0000 -60.0000
v 90.0000 0.0000 -60.0000
……

#法線
vn 0.0000 1.0000 0.0000
vn 1.0000 0.0000 0.0000
然後頂點index是用「第1個位置,第1個法線」、「第2個位置,第1個法線」、「第1個位置,第2個法線」這樣定義,點被兩個面共用的時候會有相同位置不同法線的情況。
而把頂點陣列給D3D和OpenGL時不能兩個頂點共用一個法線或一個位置,每個頂點必須「位置1,法線1」、「位置2,法線2」一整組,有相同的就要重覆寫兩次,但Blender沒做這個處理。

鈷寶:主人……,試試這個……,沒用?
PMDEditor和PMXEditor雖然有載入obj的選項,但是用了以後卻什麼也沒發生,原因不明。

用另一個軟體:3dAce看看,用3dAce轉成.x,再用PMDEditor轉成pmd,這樣稜角對了,姑且先這樣用。
3dAce作者網站(日文)

看起來都是平面是因為還沒做貼圖,也還沒調整打光。



第二關

艾莉兒:主人,美術畫好貼圖了,來實裝看看吧。
結果有貼圖的情況下,3dAce的方法也會出問題。

俗話說不要重新發明輪子,但是別人的輪子有瑕疵的時候,也只好自己發明一個了。
只好派我的鈷寶上場了。

參考這兩篇寫個命令列程式來轉換格式。
MikuMikuDance Wiki:PMD格式說明
Wikipedia:obj格式說明

…………

寫好了,動手吧:objtopmd.py stage01.obj。
鈷寶:……(讀取obj和mtl檔),……(解析、把頂點拆開),……(輸出PMD檔)。
(她有無口屬性,埋頭工作時不發一語,有時候會看不出她在做什麼請見諒。)
鈷寶:姊……好了。

也因為法線會錯的問題,沒辦法在Blender裡編輯模型,想對模型做什麼修改得靠自製的工具。

還有一個小關卡,有一張貼圖是用DXT演算法壓縮的DDS格式,我想DDS格式算是業界標準,遲早會用到,就順便幫艾莉兒做了。

艾莉兒:取得新技能:DDS格式支援,很好,這一關過了。

(不過alpha還沒支援,3D要畫半透明物件比較麻煩,polygon排序要自己做而不能用Z buffer)
(畫質也有些小瑕疵,後面會用一些技術改善畫質)



第三關

由於美術人員對世界觀還有些不了解,於是我列出模型要修改的地方,並畫了個簡圖。

把遠處的窗戶和天空拿掉,並且將房間改成兩層以配合前景的地形。


艾莉兒:總算比較像我們住的地方了。
  我們在電腦裡的空間,跟人類的世界不一樣。
  還有我們會飛,建築不用照人類的規矩。

還有一些錯誤,要叫美術修。



Stage 4

再修一些細部之後模型形狀可以了,再來調整其他地方。

a.鈷寶:主人,打光參數……,要不要……叫美術調?
目前為止其實都沒針對各個材質調,都用預設值。
美術人員似乎也不知道ambient、diffuse、specular的意義,跟他解釋了一下。

途中:用PMDEditor查看模型內部數值。


b.艾莉兒:模型有鋸齒邊不太好看,這也修一下吧。
  我記得有個方法,好像叫multisample來著的,用用看吧。


對方先試著調整右邊兩個櫃子的specular。


放大看multisample的效果,左邊是不使用,右邊是使用multisample。


觀察工作管理員顯示的資料,multisample的效能消耗似乎比較高,不過也不會因此lag。
早期或許要讓玩家可以在Option開關反鋸齒,玩家的配備會lag的時候可以設成較差的畫質減輕負載,但現在的硬體比那個時候好很多了,能應付比較複雜的計算。想參考一下現在的3D遊戲都怎麼做,是一定開啟還是做成可設定。



Stage 5

再做兩個改良
a.目前各材質的貼圖都是分開的圖檔,把它們全放在一張大圖上,合併成一個圖檔。
美術人員試了一下,3DS Max的合併貼圖功能並不聰明,如果多個物件用相同的圖檔它不能辨識出來,會輸出很多重覆的圖。

又一個有問題的輪子,還是得靠我的電子妖精了。
這次讓鈷寶進入Inkscape裡工作(寫個Inkscape外掛)。

先在Inkscape人工排貼圖……,弄好了,開始修改模型檔吧。

對了,模型檔路徑是D:\……\background\stage01\back1.pmd

鈷寶:……(整理Inkscape圖像物件的坐標)。
鈷寶:……(拿著一疊資料轉身)
鈷寶:……(修改PMD檔的貼圖檔名和貼圖坐標)。


弄好了,減少貼圖數量以後效能消耗也減少了。

b.實裝mipmap,上面幾張圖的桌子隔板有奇怪的紋路,mipmap可以消除這種紋路。
至於mipmap如何產生,先用容易看到結果的方式,在你執行的時候叫顯卡即時產生吧。
艾莉兒:好,我試試看。

這次的成果。
tilemap也實裝了,如之前所說,因為一直找不到人只好我自己來畫。


比較一下mipmap的效果,右圖是使用mipmap。


右圖是沒有紋路了,可是遠處變得很模糊。
我是知道解法:把內插方法改成anisotropic(非同向性內插),但多一些效能消耗,同樣想知道現在的3D遊戲一般怎麼做,是強制開啟、不使用、還是可在Option裡調整。

還有個問題是,有些部位的顏色錯了。
艾莉兒:我看看執行過程……,有些貼圖坐標正好在邊緣,相鄰的其他部位也拿來內插了。
貼圖坐標正好在邊緣的話(即UV其中一個是0.0或1.0),貼圖分離時不會有問題,但合併後就有下圖的情況,相鄰的像素也被拿來計算。


艾莉兒:這該怎麼解呢?
只有請美術人員修改貼圖了,貼圖之間留空隙,還有各別的貼圖改小一點,現在這樣圖太大沒辦法挪出空隙。

艾莉兒:到這裡有點累了……,可是還沒完成,要和主人繼續努力。
鈷寶:嗯……(點頭)。



這次比以往的技術研發來得困難:
  • 有些事還是當面討論比較能講清楚,這位美術人員不能約出來見面討論,只能靠e-mail溝通。
  • 對方有畫圖底子、會建模,但沒有遊戲美術的經驗,需要學習。
  • 我也是第一次寫3D程式,在公司都是負責server,沒機會碰畫面的部分,而業餘製作目前為止都是2D。
  • 兩人用的軟體不同,他用3DS Max我用Blender,技巧不一定能互通。
  • 別人做的工具有問題,得自己開發,這次特地新做了兩個工具。
但是為了把遊戲做出來,各種難關不勇敢面對不行。

一開始是想說有現成的工具可用所以選了PMD,但實作了以後,開始考慮要不要自己開發一個格式了。除了轉檔工具有問題以外,有些進階技術要模型檔裡有相關資料才能使用(如normal map、shadow volumn),PMD和PMX就沒辦法了。
別人的輪子有時候有不夠靈活的缺點,很多3D引擎也根據自身需求有自訂的格式。
不過這些進階技術也要美術人員會用才能發揮,做遊戲不是只有帶頭的人而已,合作夥伴能力不足的話遊戲整體品質也無法提升。

另外有些設定想參考其他3D遊戲怎麼做:multisample、非同向性內插要不要讓玩家可調整,還有mipmap縮小的層次要事先做好存入檔案,還是圖檔只存第一層,其他的叫顯卡即時產生。雖然是效能和畫質的取捨,但是現在的硬體應該都能輕鬆應付了,我在測試過程中也沒有lag。

沒有留言 :

張貼留言