教孩子寫遊戲:矩陣在3D遊戲編程中是如何被使用的?

2020-12-09 我是遊戲小胡

「學」的部分

通過上一節的內容,我們已經知道關於矩陣的兩個重要知識點:矩陣的由來和矩陣的乘法。

這個時候,大部分人腦子裡估計都會有個疑問:矩陣只不過是數學家換一種方式的「戲法」罷了,具體有什麼作用?

如果這個世界上沒有電腦,我們還停留在用紙和筆計算的時代,那矩陣真的沒什麼用(其實,當時數學家發明矩陣就處於這樣的時代背景下,所以,數學家的思維一直都是超前的)。在大多數人的眼中,矩陣除了可以快速解多元一次方程外,沒有其他任何用處。說真的,在現實生活中,我們用到矩陣的地方也非常非常少。

我一直把某一個道理信奉為真理:如果你覺得某個問題難以解決,不妨好好去學一學數學,沒準兒,數學家在好幾百年前就已經有了解決方法了

矩陣就是這樣,當時被發明出來的時候很多人並不理解,一個快速計算方法有什麼用?直到有了計算機,直到程式設計師在處理計算機3D問題時遇到了非常大困難的時候,大家才發現矩陣的真正用處——它能大大提高3D問題中複雜計算的效率。

打個比方你就明白了。在電腦上運行3D程序,就好比是在路上開車。而矩陣,就相當於是一個額外的氮氣加速器。假設,在沒有矩陣的情況下,車子只能開10碼,那麼,有了矩陣之後,車子就能開到200碼的樣子了。

在程式設計師使用矩陣之前,他們也不知道計算機在處理矩陣的時候那麼給力,所以,這應該算是一個意外之喜吧?

好了,大致了解了前因後果之後,我們來看一看矩陣在3D遊戲編程中到底怎麼用吧。

一、虛擬3D中的3D物體需要有哪些操作?

我們再簡單複習一下遊戲中的3D世界。第一步,我們要在一個虛擬的3D坐標系中構建3D世界;第二步,我們把各種各樣的3D物體加入到這個虛擬世界中;第三步,就是用虛擬攝像機把虛擬場景拍攝下來。

這個過程中,第二步是處理3D物體的過程,現在,我們稍微深入了解一下。

假設,我們要在3D世界中加入一輛小汽車,並讓小汽車停在預定的停車位中。我們要如何解決這個問題呢?其實,方法挺容易的。

1.用3D軟體創造一個小汽車的模型,並按照一定規則導入到我們的程序中。一般來講,軟體生成的小汽車模型會有一個中心點,而小汽車模型就是圍繞這個中心點構建起來的。在程序中,我們一般用一個結構類型(第6節的知識點)來存儲這個小汽車模型,在這個結構中,會保存小汽車的所有模型數據,還會保存小汽車的其他屬性,比方說位置之類的。

2.然後,我們要確定3D世界中停車位的具體位置朝向。有了位置,我們就可以把小汽車移動過去,有了朝向,我們就可以把小汽車轉到正確的方向上。

3.當然,我們小汽車模型的大小可能不對,所以,我們要按照虛擬世界中物體的大小來縮小或放大這個小汽車模型(由於我們有小汽車模型的所有詳細數據,不管是放大還是縮小,都不會影響小汽車的精度)。

3個步驟做完後,這個導入的小汽車就能來到我們預定的位置上了。

我們再仔細看看上面的步驟,你會發現關鍵的地方有3個:

關鍵一:移動小汽車的位置;

關鍵二:旋轉小汽車;

關鍵三:縮放小汽車。

實際上,這3個關鍵點是所有3D物體共有的特徵點,也是所有的特徵點。換句話說就是,任何一個3D物體,只要經過了這3個關鍵步驟,就能到達我們預先設想的位置上了。

這3個關鍵步驟都有專業的名詞,關鍵一叫做平移,關鍵二叫做旋轉,關鍵三叫做縮放

但是,在3D遊戲編程中,這3個步驟的順序並不是這樣的,而是按照先縮放、再旋轉、後平移的步驟進行的。

二、從旋轉開始

為什麼是縮放->旋轉->平移的步驟呢?

還是拿小汽車為例。當小汽車從數據變成圖形的時候,最開始是處於虛擬3D坐標系原點的,而且,初始的小汽車模型數據是優化過的,其中很多數據都是對稱的或者乾脆是0,也就說,最原始的小汽車數據是最容易處理的。這3個步驟中,平移是最簡單的,縮放稍微複雜些,旋轉是最複雜的了。

如果我們先平移後旋轉,就相當於讓簡單的平移把最原始的優化數據破壞了,數據一旦被破壞就會變複雜,然後,這個「複雜化」的數據再進行旋轉的話,會加大CPU的負荷。

如果我們先旋轉後平移,相當於最優的數據先進行複雜計算,然後再進行簡單的平移計算,就能大大提高3D圖形數據的處理速度了。

明白了這一切之後,我們再深入了解一下3D物體的旋轉。

由於上面先旋轉後平移的原則,我們的旋轉都是在3D坐標系原點進行的。一開始我們會覺得旋轉很簡單,不就是轉動個角度嗎?仔細一想發現並不簡單,因為物體是自由的,它可以繞著任何一條直線進行旋轉,問題一下子就變得複雜了。

但是,根據程式設計師們的經驗,任何一個物體的複雜旋轉問題,都可以分解成相對簡單些的「繞軸」旋轉,也就是繞著x軸、y軸或者z軸之一進行旋轉。因為任一旋轉軸都可以看成是一個向量,這個向量可以分別在三個軸上進行投影,某個物體繞著該軸旋轉的時候,我們可以用三角函數的知識得到該物體繞3個軸分別旋轉了多少角度。總而言之一句話,繞著3個方向軸的旋轉,可以合成3D物體的任意旋轉。

所以,我們只需要知道,一個3D物體繞某個方向軸旋轉應該如何計算,然後,我們就可以處理3D物體的任意旋轉了。

我們可以把問題再簡化一下,這迴旋轉的不是小汽車了,而是一個立方體(旋轉的原理是一樣的),立方體的正中心就處於3D坐標軸的原點。

好了,我們試著讓這個立方體繞著z軸順時針旋轉一個角度θ。

你發現了什麼?沒錯,一個立方體繞著z軸旋轉的時候,裡面任意一點的z坐標是不變的。為什麼z坐標不變呢?你想一想,要改變立方體的z坐標,是不是需要讓立方體在z軸方向上移動呢?而現在,立方體只是繞著z軸旋轉,根本就沒有移動。如果把這個立方體投影到z軸上(降到一維),它就變成了一條直線,而旋轉的過程中,這條直線是不會變的。

也就是說,立方體繞著z軸旋轉,我們只需要重新計算旋轉後的x、y坐標就可以了,然後,這個相對複雜的3D問題一下子就變成一個2D問題了。

在3D遊戲編程中,所有的3D物體都是由一個一個小點組成的,也就是說,立方體的旋轉過程,可以簡化成一個又一個點的旋轉。接下來,我們就在2D坐標系下推導一下任意一點的旋轉計算過程。

相關焦點

  • 教孩子寫遊戲:3D遊戲編程離不開矩陣,我們要如何理解矩陣?
    矩陣,可以說是本課程中的第一塊硬骨頭。雖然說,我們不需要對矩陣有非常深入的理解,但是,這並不代表著我們可以不學矩陣。這麼說吧,如果你對矩陣一無所知,那麼,整個3D遊戲編程你是學不懂的。你可以靠著強大的記憶力把本課程的代碼記住,並且也能通過自己的摸索寫出類似的3D遊戲來,但是,你對其中的原理是不理解的,將來想要寫功能更強大的3D遊戲,就純粹是天方夜譚了。但是,擺在我面前的難題是:一個成年人想要學習矩陣都有點困難,如何讓小孩子也明白矩陣的一些道理呢?
  • 教孩子寫遊戲:3D遊戲編程的必備數學知識,理解三維空間向量
    因為我們要寫的是3D遊戲程序,所以,我們必須要接觸兩個數學方面的難點知識——向量和矩陣。有的人問:這個這麼難,我們可不可以不學?我的答案是這樣的:如果你是有心要學習本課程,那麼這個是必須要學習的,是沒有道理可講的,是想破了腦袋也要學明白的。
  • 教孩子寫遊戲:計算機語言那麼多,為何3D遊戲編程偏愛C++語言?
    「學」的內容:在充分理解了計算機是個什麼玩意兒之後,不用我說你都知道,想要寫程序,就要用到計算機語言。通過上節課我們可以知道,電腦是有非常多強大功能的,可是,電腦自己並不會用它自己的強大功能,需要我們通過一定的方式告訴電腦,你應該如何使用。
  • 教孩子寫遊戲:我們將要編寫的這個3D遊戲程序什麼樣?
    如果說,這是一套教你寫一個2D遊戲的教程,那麼這一章就是多餘的。可我們學的是3D遊戲編程,提前知道最終的遊戲會寫成什麼樣子,對你接下來的學習過程是有很大幫助的。通過上一節的內容,我們已經知道,3D遊戲的編寫過程,就是模擬「拍電影」的過程,只不過,一切需要的「道具」都需要程式設計師自己去「虛擬化」。
  • 教孩子寫遊戲:遊戲編程,「學」是一部分,關鍵在於「習」
    雖然編程是一項腦力勞動,但是這項腦力勞動歸根結底是建立在一定的基礎內容之上的。除非是超級天才,否則沒有哪一個程式設計師能夠不靠前人的基礎編程成果來寫程序。所以,想要讓寫程序從體力勞動變成腦力勞動,必須有異常紮實的基本功。
  • 少兒遊戲編程:孩子學習遊戲編程有哪些好處?
    其實,孩子一旦接觸手機,就不可能有折中的狀態。有一個非常古老的辦法,就是另外找一個刺激點,把孩子的興趣從手機遊戲上吸引過來。如果這個新的刺激點是學習某項內容,豈不是很完美?我個人的建議是,把孩子的興趣從玩遊戲轉移到製作遊戲上,也就是說,我們通過教孩子如何編寫電腦遊戲,來轉移孩子的注意力。
  • 3D遊戲編程:Direct3D幫我們做了哪些事情?
    「鄙視鏈」在年輕程式設計師中不算明顯,主要是在那些「資深的」、年長的程式設計師圈子中比較常見。尤其是會寫3D遊戲的老程式設計師,目光是非常高的,他們甚至會看不起DirectX!DirectX的技術中,讓所有程式設計師都佩服的地方有兩個:其一,就是COM技術;其二,是DirectX虛擬了所有的硬體,讓遊戲編程不再考慮繁瑣的硬體控制。第二點怎麼理解呢?
  • 教孩子寫遊戲:在Windows下寫3D遊戲,為什麼需要DirectX?
    而且,這個課程是為了激發小孩子的興趣,你不學紮實一點,如何引導小孩?有了框架之後,我們就可以把遊戲內容寫在窗口之中了。那麼,接下來,我們要直接開始寫遊戲核心內容嗎?我想,你的答案和我一樣:不是的。3D遊戲和2D遊戲有著本質的區別。2D遊戲其實可以看成是一個可以操控的動畫而已,程式設計師只需要按照一定的規律把一些二維的圖片顯示在屏幕上就可以了,而計算機屏幕本就是二維的,是一個一個的像素矩陣,顯示起來其實是很簡單的一件事情,根本就不需要消耗太多的CPU資源。
  • 教孩子寫遊戲:如何通俗地讓孩子明白遊戲在電腦上的運行過程?
    理解透徹的意思,不僅僅是要懂得普通程序的運行過程,而且還要懂得這些運算過程是如何變成計算機加法的,甚至還要懂得CPU的電流結構。我想,絕大部分人就算花一輩子的時間也難全面了解。但是,我們要寫程序,一定要懂得程序的運行過程,否則寫程序的時候容易一頭霧水。所以,我把遊戲程序的運行過程分解成了如下的幾個知識點,這樣的話,你給孩子轉述的時候也會方便許多。
  • 宅在家裡別閒著,和孩子一起研究這些少兒編程軟體如何使用!
    在這個關鍵節點上,在家呆著就是我們能為抗擊病毒所做出的最大的幫助,在家也不要閒著,和孩子一起研究一下這些少兒編程應用是如何使用的
  • 3D遊戲編程:初始化Direct3D的過程
    通過前面的課程,你已經對遊戲編程有了一個整體上的認識,就算不知道細節,但也足夠你出去「侃大山」了。從這一節內容開始,我們將要深入3D遊戲編程的細節。如果遊戲編程是一個複雜的機器,前面的課程已經幫你窺得全貌了,現在的你,只是機器中的原理和細節不太明白。
  • 教孩子寫遊戲:作為新手,要如何理解遊戲中的3D世界呢?
    總結一下,就是把3D世界抽象成數學問題,然後,我們就可以在電腦中構建虛擬的3D世界了。再回到上面的例子。我們可以用一堆數字A來表示你的房間,然後用另一堆數字B來表示電視,想要在房間A中放個電視,就把B這堆數字按照一定的規律放進A中。那麼,如何通過數學來構建一個虛擬的3D世界呢?
  • 3D遊戲編程:遊戲代碼的整體結構是什麼樣子的?
    為了能讓作為初學者的你學明白3D遊戲編程,我花費了17節的內容來講了一些「廢話」,只是希望你不要忽略這些「廢話」。3D遊戲編程實在是太複雜了,如果可以的話,我還想說一些更深層次的內容。但是我不能這麼做,過深的東西講得太多了,很容易「勸退」的。
  • 如何製造一個簡單的2D遊戲?
    除此之外,一些相對輕量的3D遊戲也可以考慮使用Unity開發,比如Monument Valley(紀念碑谷)、The ROOM(謎室)、Outer Wilds(星際拓荒)、The Almost Gone(憶落謎境)、Kerbal Space Program(坎巴拉太空計劃)等等。(上面舉例的遊戲都很好玩XD!感興趣可以玩玩看。(明日方舟也是用Unity開發的!(嘗試抓人入教.
  • 教孩子寫遊戲:稍微深入了解一下DirectX
    遊戲編程和其他編程不同的地方在於,遊戲編程對程式設計師的要求更高。說一句不太好聽的話:一般的編程都有例子可以「抄」。我相信,很多人都在網上看過類似這樣的段子:A:最近好累,寫程序寫得頭大!B:累?寫程序不都是複製粘貼嗎?
  • 遊戲引擎是什麼?它與遊戲和程式語言是什麼關係? - 麥大麥
    先給出遊戲引擎的定義把:遊戲引擎是指一些已編寫好的可編輯電腦遊戲系統或者一些互交式實時圖像應用程式的核心組件。這些系統為遊戲設計者提供各種編寫遊戲所需的各種工具,其目的在於讓遊戲設計者能容易和快速地做出遊戲程序而不用由零開始。
  • 創客的起點:孩子能在遊戲中學會編程
    在11歲的時候,他和他的小夥伴使用BASIC和Turbo Pascal開發出了人生第一個遊戲;到現在,他已經是腰纏萬貫的巨富了。為「編程一小時」制定的Minecraft中使用了一種名叫Blockly的模塊化的程式語言。在這門語言的各個模塊的底下則是真正的JavaScript。孩子們將使用這些模塊來編程以解決14個Minecraft主題的難題。
  • 兒童編程,就是讓孩子玩遊戲?
    但是深度接觸了scratch這類少兒編程的學習之後會發現,我們其實不用去牴觸這些。 孩子玩遊戲不好的原因是孩子被遊戲帶歪了,從而會沉迷於遊戲影響了學習,但是如果反過來讓孩子主動去「玩」遊戲,讓孩子成為主導體,去控制遊戲、製作遊戲,那麼這些電子產品則可以發揮其有益的一方面!
  • 學習遊戲編程,我們都要做什麼?
    遊戲包含了很多人的夢想,大部分現實中無法做到的事情,遊戲中都能做到,也能在平平無奇的日常生活中,為我們帶來刺激感。對於想學遊戲編程的朋友們,小編這裡推薦C++以及學習之後的流程:C++的學習不用非常深入,學習之後在數據結構上下點功夫,學到樹就可以了,樹和圖可以留到以後看,之前的鍊表堆棧隊列都看掉,爭取自己寫出來。然後學下SDL,這個包很容易學,看網上的教程幾天就學會了,然後接下來就是從最傻逼的遊戲開始寫。
  • 玩遊戲學編程:8個能夠快速提高編程水平的小遊戲
    這些問題有一個解決方案,它適用於學習如何編寫代碼或提高您對特定語言的知識。編程遊戲!今天我們將列出一份最佳編程遊戲的列表。1. Robocode在Robocode中,你必須使用一些流行的程式語言為你的機器人坦克編寫AI,包括Java和c#。所以每次你玩遊戲的時候,你都可以練習你真正的和適用的編碼技巧。這是一個開源遊戲。Robocode是一個完全開源的項目,這意味著你可以重用它來製作你想要的任何東西。多年來,粉絲們一直在為Robocode創建各種模式和附加組件。