修改新增 : 範例程式增加
準備好XNA的C#邊及專案以後,接下來的工作就是將美術人員給我們的3D模型資訊檔案(FBX),加入到程式中。
首先,我們要先加入一個Model的物件,這代表著就是你現在要代表3D模型的變數。
Model : 呈現一個3D Model由多個ModelMesh物件的單元所組成。
Model FD;
接下來就是使用Content Pipeline的方式載入FBX檔案。
FD = Content.Load<Model>(@".\mesh\FD");
這邊可能用@,這樣就可以直接輸入路徑,而不需要再\\來指定。
因為我現在要匯出的當案型態為Model,所以在Content.Load<T>的T就要用Model。
這樣在執行期間,在LoadGraphicsContent的時候,Content就會用PIPELINE的方式載入所需要的檔案。
再下來就是進入到DRAW()的函式,在這個函式中,我用一個函數來繪製模型,而傳入的參數就是剛剛載入的Model。
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
DrawModel(FD);
base.Draw(gameTime);
}
接下來就是來寫DrawModel函式的內容。
將一個3D世界中的物體,轉換成在2D我們螢幕畫面時,需要經過三個矩陣的轉換
World : 世界轉換矩陣,這個矩陣可以由三個部分組成。
S : Size,表示放大的倍率,可以針對XYZ軸分別放大。用Matrix的CreateScale函數指定XYZ分別的放大倍率。
R : Rotation,旋轉,這邊XNA的Matrix類別,提供幾個方建的旋轉函數。CreateRotationX(針對X軸旋轉)、CreateRotationY(針對Y軸旋轉)、CreateRotationZ(針對Z軸旋轉)。
T : Translation,平移,這邊可以說成是,3D Model在3D世界中的位置。用Matrix的CreateTranslation就可以指定位置。
全部設定好以後Matrix world結果是寫成S*R*T的計算結果值。
View : 一個觀察者在一個3D空間中的位置,用Matrix的CreateLookAt函數設定就好,這個函式需要四個參數。
Position : 觀看者的位置,也就是攝影機現在在的位置,可以用一個Vector3的方式可以完成指定座標位置就好。
LookAt : 觀看者現在要看的位置,就是觀看者現在要看哪個點,也是用一個Vector3就可以描述完成。一般來說我們都會把物體放在原點上面,所以觀看位置都是填入000,在XNA中,Vector提供了一個方式,這樣就不用特別的再填入那些數值,用Vector3.Zero就可以。
Up : 向上的向量,一般都不會特別設定他,都直接用Vector3.Up代表010,這邊要注意的是,在匯出FBX的時候,他會問你說Up Vector是在哪個軸,在預設的3D Max中Z軸向上,所以在匯出的時候大家記得把Y軸改成Z軸。同時大家也可以把Vector3.Up改成Vector3.Down這樣會發現上下會顛倒。
Matrix.CreateLookAt(位置,觀看的位置,Up)
Projection : 投影矩陣,用Matrix所提供的CreatePerspectiveFieldOfView來建置。
這個參數需要四個參數:
視野參數 : 眼睛所能看到的最大角度
aspectRatio : 解析度的比值
近平面 : 最近所能看到的距離。
遠平面 : 最遠所能看到的距離。
這邊有個概念就是近平面與遠平面,所圍成的立體椎體,稱為平頭椎體。這個在3D圖學有自己的獨特的意義,就是說在這個椎體內的東西,才會畫出來,而超過這些椎體的範圍都不會匯出。
以上三個重要的矩陣設定好以後,接下來就是進行匯出的準備。
我們需要一個Matrix陣列用來儲存,目前那個3D Model有多少的元件(物件)。
Matrix[] transforms = new Matrix[FD.bone.count];
接下來就是將FD Model的東西放入transforms中
FD.CopyAbsoluteBoneTransformsTo(transforms);
這種複製不是單純的複製陣列或是物件,他會記錄所有物件與父類別的相對位置等等。
這些準備完成以後接下來就是,針對這個矩陣陣列來做WVP轉換。
用兩層FOREACH迴圈來完成,轉換動作
foreach (ModelMesh mesh in FD.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
//預設光源
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index] * World;
effect.View = View;
effect.Projection = Projection;
}
mesh.Draw();
}
完成以後大家就可以編譯這個檔案,就會發現3D模型的呈現。
範例程式:
140.126.21.8/~b09402129/XNA/example4.rar
最後有一點要提醒, 這點美術人員應該要特別注意。
建議你把所有物件的中心點都設置在原點的位置,有些人有自己的特殊喜好,但是會帶改程式人員很大的困擾,因為程式人員需要尋找你那張圖片在哪裡。
再來美術人員需要把你現在3D模型的長寬高都告訴,程式人員,這樣可以減少程式人員在那邊尋找哪邊是最好的視野位置。
準備好XNA的C#邊及專案以後,接下來的工作就是將美術人員給我們的3D模型資訊檔案(FBX),加入到程式中。
首先,我們要先加入一個Model的物件,這代表著就是你現在要代表3D模型的變數。
Model : 呈現一個3D Model由多個ModelMesh物件的單元所組成。
Model FD;
接下來就是使用Content Pipeline的方式載入FBX檔案。
FD = Content.Load<Model>(@".\mesh\FD");
這邊可能用@,這樣就可以直接輸入路徑,而不需要再\\來指定。
因為我現在要匯出的當案型態為Model,所以在Content.Load<T>的T就要用Model。
這樣在執行期間,在LoadGraphicsContent的時候,Content就會用PIPELINE的方式載入所需要的檔案。
再下來就是進入到DRAW()的函式,在這個函式中,我用一個函數來繪製模型,而傳入的參數就是剛剛載入的Model。
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
DrawModel(FD);
base.Draw(gameTime);
}
接下來就是來寫DrawModel函式的內容。
將一個3D世界中的物體,轉換成在2D我們螢幕畫面時,需要經過三個矩陣的轉換
World : 世界轉換矩陣,這個矩陣可以由三個部分組成。
S : Size,表示放大的倍率,可以針對XYZ軸分別放大。用Matrix的CreateScale函數指定XYZ分別的放大倍率。
R : Rotation,旋轉,這邊XNA的Matrix類別,提供幾個方建的旋轉函數。CreateRotationX(針對X軸旋轉)、CreateRotationY(針對Y軸旋轉)、CreateRotationZ(針對Z軸旋轉)。
T : Translation,平移,這邊可以說成是,3D Model在3D世界中的位置。用Matrix的CreateTranslation就可以指定位置。
全部設定好以後Matrix world結果是寫成S*R*T的計算結果值。
View : 一個觀察者在一個3D空間中的位置,用Matrix的CreateLookAt函數設定就好,這個函式需要四個參數。
Position : 觀看者的位置,也就是攝影機現在在的位置,可以用一個Vector3的方式可以完成指定座標位置就好。
LookAt : 觀看者現在要看的位置,就是觀看者現在要看哪個點,也是用一個Vector3就可以描述完成。一般來說我們都會把物體放在原點上面,所以觀看位置都是填入000,在XNA中,Vector提供了一個方式,這樣就不用特別的再填入那些數值,用Vector3.Zero就可以。
Up : 向上的向量,一般都不會特別設定他,都直接用Vector3.Up代表010,這邊要注意的是,在匯出FBX的時候,他會問你說Up Vector是在哪個軸,在預設的3D Max中Z軸向上,所以在匯出的時候大家記得把Y軸改成Z軸。同時大家也可以把Vector3.Up改成Vector3.Down這樣會發現上下會顛倒。
Matrix.CreateLookAt(位置,觀看的位置,Up)
Projection : 投影矩陣,用Matrix所提供的CreatePerspectiveFieldOfView來建置。
這個參數需要四個參數:
視野參數 : 眼睛所能看到的最大角度
aspectRatio : 解析度的比值
近平面 : 最近所能看到的距離。
遠平面 : 最遠所能看到的距離。
這邊有個概念就是近平面與遠平面,所圍成的立體椎體,稱為平頭椎體。這個在3D圖學有自己的獨特的意義,就是說在這個椎體內的東西,才會畫出來,而超過這些椎體的範圍都不會匯出。
以上三個重要的矩陣設定好以後,接下來就是進行匯出的準備。
我們需要一個Matrix陣列用來儲存,目前那個3D Model有多少的元件(物件)。
Matrix[] transforms = new Matrix[FD.bone.count];
接下來就是將FD Model的東西放入transforms中
FD.CopyAbsoluteBoneTransformsTo(transforms);
這種複製不是單純的複製陣列或是物件,他會記錄所有物件與父類別的相對位置等等。
這些準備完成以後接下來就是,針對這個矩陣陣列來做WVP轉換。
用兩層FOREACH迴圈來完成,轉換動作
foreach (ModelMesh mesh in FD.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
//預設光源
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index] * World;
effect.View = View;
effect.Projection = Projection;
}
mesh.Draw();
}
完成以後大家就可以編譯這個檔案,就會發現3D模型的呈現。
範例程式:
140.126.21.8/~b09402129/XNA/example4.rar
最後有一點要提醒, 這點美術人員應該要特別注意。
建議你把所有物件的中心點都設置在原點的位置,有些人有自己的特殊喜好,但是會帶改程式人員很大的困擾,因為程式人員需要尋找你那張圖片在哪裡。
再來美術人員需要把你現在3D模型的長寬高都告訴,程式人員,這樣可以減少程式人員在那邊尋找哪邊是最好的視野位置。
文章標籤
全站熱搜

恩~~這基本上都知道如何貼上3D模型了 但是我陷再遇到一個問題 就是3DMAX匯出模型後(我只是用很簡單的BOX不過我把它其中一面刪掉) 丟到這個程式執行 居然沒有背面的顏色 不知道這是怎麼一回事 這是在3DMAX裡就要設定還是由程式來設定可以看的到背面的顏色呢?
你所謂的沒有背景顏色是甚麼意思? 這邊有點看不太懂
直接用途說明好了^^a http://www.cs.pu.edu.tw/~s9471115/project/11.jpg 這是3DMAX掃圖出來正確顯示的畫面 http://www.cs.pu.edu.tw/~s9471115/project/12.jpg 而這是丟到程式裡執行的畫面 為何他會沒有顏色呢 直接透明?@@|||
有以下情況,如果你的面是用貼材質的方式可能材質他找不到路徑 再來就是套用預設的EFFECT的問題,燈源設定等... 如果方便的話可以借看一下CODE嘛,把整個專案借我看一下
http://www.cs.pu.edu.tw/~s9471115/project/test1.rar 抱歉前面那篇可以砍了忘了加最後一個r
嗯 我剛剛幫你看了(還在另外一台電腦安裝SOFTIMAGE 囧) 你在3D MAX上面看到的是他預設的設定值,感覺起來像是材質的一種... 當你匯出以後,因為3DMAX都喜歡講材質,放在自己的目錄底下... 我用SOFTIMAGE開啟你的模型,如下圖 http://xs227.xs.to/xs227/08201/model420.jpg 可以看到,他預設的顏色,就是天空藍,3DMAX我不知道在哪邊設定,因為我沒有用過那套,用SOFTIMAGE的話,很清楚可以COLOR你設定的值... 所以這就是問題所在了 PS 他不是變透明,他是套用預設顏色
恩~~的確我給他的材質是天空藍 他是可以顯示出來沒錯 可是在程式執行後面跟裡面的顏色為什麼沒有顯示出來呢?就像3DMAX掃圖那樣可以顯示出背面的顏色和裡面的顏色 是還需要在程式上動手嗎?
背景顏色,你說的是黑色?跟紫色?
http://www.cs.pu.edu.tw/~s9471115/project/123.jpg 就是要顯示圖片中的那些區域的顏色 而且BOX整體的線條也看的太出來 不知道這是什麼原因@@||
嗯 這個應該是你模型繪製的問題 我剛剛在SOFTIMAGE隨便拉一個CUBE,結果丟進XNA是正常顯示 可能跟你繪製方法有差別,你是自己手動拉平面的? 試試看MAX內建的CUBE吧
恩~~好像似乎真的是我那個不行 自己用MAX的BOX物件堆成長方體好像才是正確的作法 我之前是只用一個BOX出來之後 給他用4*4*4的格線 之後再轉成poly然後選擇4*4的一面全部刪掉 可是裡面卻是黑的沒有顏色 MAX掃圖倒是可以在shader參數把2-Sided打勾然後掃圖就可以看到裡面的顏色了 問題來了這是不是就是這程式範例沒有寫shader的關係所以才顯示不出來呢? 其實是可以顯示出來的只是因為沒有寫shader的關係
這點你可以試試看~ 因為我目前對於SHADER沒有這麼深入的了解
現在又有新問題了^^a 將3DMAX上材質後給他Bitmap貼圖 貼在整個模型上 輸出後丟到程式上面執行 建置時出現 錯誤Invalid texture. Face 0 is sized 572x446, but textures using DXT compressed formats must be multiples of four. 不知道這是什麼問題
模型貼圖要是2的N次方大小 128*128 256*256等 應該是這個問題
= =|||還有這種規定阿 所以要再模型在上貼圖還不能隨便一張圖囉 怎麼感覺這麼麻煩阿= =||| 想說只是想要把一張圖片貼在模型上顯示而已 還要計算這些東西真是太神奇了 因為在3DMAX很自然的貼上去根本不會有錯誤 為何程式會管到圖片呢? 不是只要模型沒問題就好了?
我是認為是這個問題 可能是關於XNA貼圖方式,像DIRECTX也是依樣用這種方式... 要不然就是匯出材質的時候,設定一下把它填滿程2的次方吧,應該繪圖軟體有這個功能
恩~~是有看到說其實XNA用的幾乎都是DirectX裡面的函數 不過我根本沒學過DirectX所以這算是第一次碰3D的東西 還真的是要碰過才會知道這懂問題= =|| 剛剛也把它改成2的次方 結果也成功了 不知道這是有什麼特別的原因嗎? 一定要二的次方? 跟二進位有關嗎?
跟二進位有關係,再來就是方便處理。 所以幾乎圖片都是2的次方數,在來就是看XNA是用甚麼方式將材質貼上去等 這些都算是為什麼用2的次方數的原因
最近在貼上自己模型的時候遇到個問題 感覺是很大的問題~~汗 請看圖 http://www.cs.pu.edu.tw/~s9471115/project/2.jpg 紅框框中的問題如何解決呢? 看到都覺得神奇 為什麼會連後面的東西也看的到 不知這是哪裡出問題了 模型應該是沒問題 因為在軟體裡面看都正常
因為我沒有程式碼所以我不知道 可能是模型本身的框框? 建議下次可以連程式碼一起放上來
http://www.cs.pu.edu.tw/~s9471115/project/1.txt 上面是主要的程式碼 我也沒做什麼改變 只是將我的場景模型和機器人模型放上去而已 為什麼會造成機器人也會看到背後的部位
如果單一看的話會有問題產生?] 沒有的話就是角度問題
恩~~單純看模型的話也會 應該不是角度問題 模型的話在3D軟體裡面看是正常的並沒有故意設定透明度之類的
這點我就比較不清楚了 目前沒有遇到這種問題
我覺得版主真的很勵害的說! 這些東西都能研究的如此透徹! 在下也小有研究程式編譯~ 而看了版主的文章後想問一些關於其他相關的問題 就是我們該如何讓在一個網頁中以建好的3D物件拼成一個新的物件,然後像許多網路遊戲那樣可以自由視野調整? 在下的假設前提是在一個網頁中,以建好的3D物件在一個物件欄中做出了一個新的3D圖來,然後「可以經由按住滑鼠左鍵並上下左右移動而視野也會跟著改變」~關於這方面的技術不知版主是否能幫在下解惑一下~如果有相關程式碼幫助講解會比較好~謝謝! 希望版主能於有空時幫幫在下探討一下這個問題~謝謝!
這個部份我目前沒有辦法回答,因為我對網頁技術不是這麼了解。 像是Silverlinght和FLEX這兩個,目前都沒有3D環境的東西,所以目前都是用模擬的方式去做。 不過不巧的是SilverLight跟Flex這部分我就不清楚了 我目前只有探討XNA的部分。 沒能答覆真的很抱歉哩
版主你好~ 在下看了您的文章覺得您的程式能力相當高深 而在下也尚有小修程式語言方面的知識 想請教版主一個問題 關於如果將些3D技術置於網頁之中 並且將近於一個物件欄中拼出一個新的3D圖來 那麼該如何在網頁中執行在下所想問的工能- 按住滑鼠左鍵不放並上下左右移動 而視野也會因此而有不同的視角(就像許多網路遊戲那樣) 不知版主是否能給在下關於此問題一些建意~如果有程式碼輔助當然會更好~謝謝!
這個問題我沒有辦法回答 不過我像其他人詢問得到了一個答案,你看看是不是你要的 http://msdn.microsoft.com/zh-tw/magazine/cc500570.aspx 他是用silver light去做的
在預設的3D Max中Z軸向上,所以在匯出的時候大家記得把Y軸改成Z軸。 啊??所以輸出FBX~UP要用Z還是Y給XNA??
基本上哪軸向上是沒有差別的 只是你要讓寫程式的人知道你現在是哪的軸是高度軸...
板主你好 我們因為專研的關係剛開始接觸XNA不久 現在正為3D貼圖煩惱中 我們已經將元件透過MAYA改為fbx檔 建構時卻顯示Missing asset "圖檔路徑" (非fbx檔(為原始圖檔png檔)) 一開始以為是程式碼寫錯,換了另一個方式寫跟匯入sourse 但是問題沒有解決 請問這應該要怎麼處理比較好??
針對於貼圖的部分 我當初在做的時候,是美術將檔案匯出成ACSII編碼檔案 然後,在手動修改貼圖的位置
載點失效了Q_Q