《視覺開發專題》之 OpenGL 3D動畫繪製&圖形學概念的理解

知識前導

計算機圖形學的終極目標——討好人類視覺系統

  最近在啃的書中有一本叫《計算機圖形學 原理及實踐》,這本書讓我深有感觸的是其緒論中對計算機構建真實感圖像的理解:咱們所致力的最終目標,是視覺形式的交流,並且主要都是與人的交流。 這句話的潛臺詞是:在求解圖形學問題和構建模型時需考慮人類視覺系統的影響。 我我的仍是深有啓發的。html

  好比視覺停留,60HZ刷新頻率就不會感到卡頓;好比最小角分辨率約爲1弧度,300ppi以上的屏幕就很難有顆粒感了;好比只能感覺必定頻率範圍的可見光,紅外紫外各類射線人類都看不到;好比人感光細胞每次接收光子的能量累積到必定量纔會產生神經信號,微弱的光須要放大瞳孔注視良久纔看得清;好比一幅平面素描畫也能讓人產生立體感,這不只僅是光陰特效能夠作到,其實任何刺激,只要能觸發視覺系統大體正確的反應,都能被識別並在大腦中造成某種感知,也正是咱們視覺系統的強大自適應能力,容許咱們在不少計算作不到徹底仿真(好比光照)的狀況下,採起一種合理的近似,依然讓結果看起來使人滿意。git

  正是人類視覺系統的特色,決定了當今全部可視設備從硬件到軟件一切的設計和進化方向。建議你們在學習一門新知識時也能夠嘗試跳出來,俯瞰一下這個領域的知識版圖和發展方向,瞭解一下「從哪裏來,到哪裏去的」的背景,說不定會讓你有新發現,好比再看到某些複雜的設計,會豁然開朗。開胃菜就到這了,下面進入咱們今天的正題。程序員

案例&知識點一覽

幾種圖元: github

3D 動畫:

上面兩個效果的源碼實現我都放在 這裏了。若是你有收穫,記得留個 star 以資鼓勵~算法

這是 視覺專題 的第二篇,上面兩個案例是使用固定管線實現的。之因此用固定管線實現,一是由於能夠更快的實現效果,再者能夠避免因不熟悉 GLSL 語法而干擾到對渲染流程的理解。 案例涉及到的知識點有:編程

  1. OpenGL 座標系統
  2. OpenGL 矩陣變換
  3. OpenGL 基本圖元
  4. OpenGL 渲染技巧
  5. OpenGL 紋理映射

結合提供的兩個案例閱讀完(還不夠 須要你帶着思考去實踐、求證)本篇內容,你將收穫:緩存

  1. OpenGL 固定管線的使用
  2. OpenGL 基本圖元的使用
  3. OpenGL 紋理的簡單使用
  4. OpenGL 幾種渲染技巧的優劣及使用
  5. OpenGL 矩陣變換與座標轉換的關係

  這裏感謝一下 CC老師_HelloCoder (一隻溫柔的胖C) 提供的視覺課程和資源,爲我快速入門圖形編程找到了方向。bash

  強烈建議下載我爲你準備好的 案例源碼,先跑起來看看每一種效果,再結合文章和本身的理解,親自嘗試不一樣的參數帶來的變化,而後改爲你但願的樣子。函數

注: 這不是一篇代碼註釋和API用法講解的文章,該有的註釋源碼裏都爲你寫好了,搜索引擎一次就能找到答案的問題也不須要我在這浪費篇幅來寫。此篇的重點是:對各個知識模塊有初步認識的基礎上,進一步加深對重點知識點的理解。oop


一. OpenGL 座標系

1. 爲何須要座標系?

  簡言之,咱們現實世界裏的一切,都因座標系的存在才能被抽象成可量化的數值:位置、長度、速度、空間、時間。往深了講,這要扯到愛因斯坦的相對論,通俗點說,座標系就是咱們認知多維世界的基石,它能爲咱們提供直觀的時空上的描述。固然,四維及以上的座標系若是從空間上去想象,以目前人類廣泛的認知,是很難理解的,暫且將它們都看作矩陣罷,相信大佬們的線性代數必定都比我好。

2. 有哪幾種座標系

模型/對象空間座標系:爲了方便計算,一般會選取建模對象的中心做爲該座標系的原點,使得模型的全部點在 x y z座標均位於 -0.5 ~ 0.5 之間。好比咱們將一個骰子建模爲立方體,以立方體的中心爲原點(不是規定的,只是爲了更方便計算而已),創建一個 右手座標系,做爲骰子的模型空間座標系。這個座標系爲骰子的全部頂點賦予了座標信息。

場景空間座標系:全部的物體模型必定會存在於一個或多個場景(一系列物體和光源組成的模型)中,包含了某個場景空間的座標系就是場景空間座標系,具體來講(打開你的空間想象力):對於上述骰子,若是它當前在一張桌子上(假設該桌面是規則矩形),桌子位於房間的正中心(假設房間是個長方體),骰子位於桌面的正中心,此時以房間的地面中心處爲原點創建 右手座標系 做爲 場景空間座標系,假設桌面的 y 座標爲 5,那麼將上面模型座標系中骰子的全部頂點座標 y 值加上 5,就獲得了它相對於這個場景空間座標系的座標了。

相機空間座標系:依然使用上述房間做爲場景,若是咱們須要顯示(看到)桌面上的骰子,那麼就必定要在房間中合適的位置放置相機(咱們的眼睛),這個合適的位置(座標)也是相對於場景座標系的。如今以相機鏡頭(咱們的眼睛)所在點爲原點,新創建一個 右手座標系(鏡頭朝向/眼睛直視的方向爲 z 軸負方向),使得上述場景空間中的全部景物都可以表示爲這一座標系中的座標,該座標系咱們稱爲相機空間座標系

像素空間座標系:上述場景中全部可見景物(落入平截椎體內的點)的相機座標最後會被轉換爲規格化設備座標 (NDC),在該座標系中,可見景物的 x、y 座標被表示成 -1 和 1 之間的浮點值,z 座標爲負值。( x、y超出[-1,1]範圍的不在相機 (眼睛) 的視域內;z > 0 的景物在相機 (眼睛) 後面),而後這些可見的點會被變換爲像素座標,就是咱們看獲得的屏幕上的像素點(視網膜裏對應的圖像),屏幕上的像素點座標系(一般(0,0)位於左上角)就是像素空間座標系
  注意:在標準化設備座標系中 OpenGL 使用的是左手座標系(投影矩陣交換了左右手)。

3. 座標系之間的變換關係

  上述座標系在計算機圖形學中,與圖形數據到顯示輸出的幾個步驟一一對應,僅憑這段描述確定不足以徹底理解它們之間的變換關係,這張圖展現了整個流程以及各個變換過程作了什麼:

  簡單說明下座標系變換的過程:

  1. 將 camera 移到準備拍攝的位置並調好方向(視圖變換,view transform)
  2. 將準備拍攝的對象移到場景必要的位置上(模型變換,model transform)

第一、2步是同一件事的兩種實現方式:物體不動相機動/相機不動物體動,因此一般將這兩步合併爲一步——視圖模型變換(model-view transform),該過程的結果就是構建一個獨立的、統一的空間系統,將場景中全部的物體都變換到場景空間座標系中。

  1. 設置相機的焦距,或調整縮放比例(投影變換,projection transform)
  2. 對結果圖像進行拉伸或擠壓,將它變換到須要的大小(視口變換,viewport transform),與第3步不一樣的是,3是改變捕獲場景的範圍,而這裏是對結果的變形。

  重點來了,敲黑板:第3步設置的焦距或縮放比例,實際上是在設置相機取景時 視錐體(上圖中的四角椎體) 的大小,圖中陰影部分爲平截椎體(frustum),在平截椎體之外的物體都會被去除,若是某個圖元正好穿過平截體的某個面,OpenGL 將會對此圖元進行剪切(clip),這是 OpenGL 的 特性,能夠解決靠近相機的物體會無限大的問題,再者,不繪製過遠或超出視域範圍的物體,能夠改善渲染的性能以及深度精度。此外,第3步還計算了用於透視投影(近大遠小效果)的參數(齊次座標(x,y,z,w)中的 w)。

4. 補充

補充(一):投影方式
  上述過程是透視投影的形式,還有一種叫正交投影/正射投影/正投影,主要用於保持物體真實大小以及相互之間角度的場景,好比建築設計圖和計算機輔助設計的領域,這裏就不贅述了。它們投影方式的區別以下:

補充(二):齊次座標
  上面提到的透視投影,相信你們對 近大遠小 的效果必定不陌生,由於一切景物的光線透過咱們的瞳孔最終在視網膜上成的像,都是透視投影的結果。但在投影空間中,會產生不少與歐式空間中相悖的感性結果,好比兩條共面平行線會相交:

兩條鐵軌的間距隨着視線變遠而減少,直至在地平線處(無限遠點)相交。

  透視空間中的圖形幾何變換,若是不能合併矩陣的乘法和加法運算,計算會十分複雜。爲了解決這一問題,德國數學家(August Ferdinand Möbius)提出了 齊次座標系:採用 N+1 個量來表示 N 維座標。例如,在二維齊次座標系中,咱們引入一個份量 w,將一個二維點 (x,y) 表示爲 (X,Y,w) 的形式,其轉換關係是:

x = X/w
y = Y/w
複製代碼

  在齊次座標系中最後一個份量爲 0 能夠表示無窮遠點:(x,y,0)。齊次座標容許將平移、旋轉、縮放及透視投影等表示爲矩陣與向量相乘的通常向量運算,這是笛卡爾座標所不具有的優勢。總之,其重要性主要有二:其一是區分向量和點;其二是易於進行 仿射變換(Affine Transformation)。

那爲何能區分向量和點?爲何更易於仿射變換呢?這篇總結爲你解惑: 齊次座標與變換矩陣。若是你沒權限下載該文檔請在評論區留言,我私發完整的 PDF 給你。

二. OpenGL 矩陣變換

扯了這麼多,那矩陣運算與物體的仿射變換之間究竟是怎樣的對應關係呢,下面咱們來一一拆解。

1. 矩陣回顧

  矩陣乘法的基本規則:

  從上圖規則中不可貴出如下結論:

  • m x n * n x k = m x k
  • 矩陣乘法的前提條件需知足 m x n * n x k 的形式, 即被乘矩陣的列數要等於相乘矩陣的維數,n維向量也能夠看作 n x 1 的矩陣
  • 矩陣的乘法是不可交換的,即AB≠BA
  • 矩陣的乘法遵循結合律:C(BA)=(CB)A=CBA,因此多個變換矩陣能夠直接按序相乘,獲得最終的變換矩陣,進而減小計算次數來提高程序性能

2. 各類變換與矩陣的映射關係

平移

  上圖所示的是一個4x4的單元矩陣,任何4維向量乘以該矩陣獲得的仍然是其自己,相似的,若是咱們但願將物體沿着 x 軸正方向平移1,而 y 和 z 保持不變,就將該物體的全部頂點 v:(x,y,z,1) 乘以該矩陣:
相似地,其餘軸方向的平移以此類推。

縮放

  若是你理解了上面平移的計算過程,縮放的矩陣其實也很好推理,好比咱們但願將一個物體變換爲原來大小的3倍,就將該物體的全部頂點 v:(x,y,z,1) 乘以該矩陣:

  由於每一個份量是單獨控制的,你徹底能夠經過修改不一樣份量的值來達到不一樣方向不一樣縮放比例的效果。另外,若是縮放時物體中心不在 (0,0,0) 處,那麼縮放也會使物體遠離或者靠近 (0,0,0),若是不想改變物體距離原點的距離,能夠用上面剛學過的平移矩陣先將物體中心移至原點處,而後再縮放,最後再用平移矩陣的逆矩陣將物體移回原位便可。

旋轉

  假設你理解了上面提到的齊次座標以及上述矩陣運算與線性變換的關係,那麼將物體全部頂點座標乘如下面這個矩陣,來猜猜是什麼操做?

  答案是,將物體繞 z 軸逆時針旋轉 θ° 。不明白?閉上眼睛,繞 z 軸旋轉是否是將全部頂點在 xy 平面內作旋轉?是否是等價於把每一個點繞其所在的二維座標系原點逆時針轉 θ° ?這幾個問題肯定了還不清楚?這實際上是道高中數學題:如何求點 p(x,y) 繞原點旋轉 θ° 至(此處爲逆時針旋轉)點 p`(s,t) 的座標。我們直接來看證實吧...其實我也愣了半天才看懂(╮(╯▽╰)╭高中數學大概都還給數學老師了)
  上述繞 z 軸旋轉的計算過程若是你弄清楚了,那麼繞 x 軸、y 軸的旋轉也都不在話下了。再結合上面已知的結合律,封裝一個支持同時繞x、y、z旋轉指定度數的函數也不難:將三個矩陣按序相乘便可。另外,與縮放效果相似,若是旋轉時物體中心不在原點,會產生物體旋轉的同時總體位置也繞原點旋轉的效果:
解決方法也一樣:將物體中心先移至原點,待旋轉結束後再移回原位:

透視投影

  相比前面的平移、縮放與旋轉,這個變換過程相對複雜,但也不用慌,咱們只須要肯定一個頂點的變換矩陣便可,由於線性關係是通用的。透視投影有兩種情形須要考慮:

  1. 中心對稱的視錐體,z 軸位與椎體的中央位置。
  2. 不對稱的視錐體,相似咱們坐在火車裏看窗外的景色,窗戶的正中心並不正對咱們的眼睛。

咱們先來考慮第一種情形:

咱們的目的,就是計算視錐體中的點投射到近平面上對應的點的座標。假設近平面的寬、高、Z 值分別爲 width、height、 Znear,遠平面的 Z 值爲 Zfar。結合空間幾何知識不可貴出其對應關係以下:
  對於第二種情形,其實就是基於前者在 xy 平面上平移了近平面的位置而已,若是近平面(一個矩形)的位置用 xy 平面內的 top、left、right、bottom來表示,那麼將變換矩陣的 x 維和 y 維的第三份量 z 根據近平面的位置作對應調整便可:
若是理解了這些,你就完全掌握 frustum系列函數的用法。若是還沒理解透徹也徹底不用懷疑本身,我這笨腦子幾乎是畫完了一本演草紙才弄清楚~相信對有線性代數基礎的你來講,這些都是小菜一碟。

3. 矩陣的理解

  目前咱們接觸到的矩陣都是圖形學裏最基本的簡單應用,關於矩陣的深刻理解,大學沒有線性代數課的我這裏就不誤人子弟了(惡補中...),待學習小有心得再與你們分享。先推薦你們讀一讀孟巖老師寫的 理解矩陣。(共三篇,建議從一開始看,博主經過直覺而非抽象的方式,把向量、座標系與矩陣的關係闡述的十分透徹:空間的本質特徵是容納運動,矩陣的本質是線性空間中線性變換的一個描述。在一個線性空間中,只要咱們選定一組基,那麼對於任何一個線性變換,都可以用一個肯定的矩陣來加以描述。)簡而言之,在線性空間中選定基以後,向量刻畫對象,矩陣刻畫對象的變換,用矩陣與向量的乘法來完成變換。 固然,這些理解和思考,也不必定徹底正確,或者說必定有某些不嚴謹之處,但它仍然能夠爲咱們更好的理解矩陣提供諸多有價值的參考。

PS:燒腦原來真的能夠有快感...emmm 別問我怎麼知道的。

三. OpenGL 基本圖元&繪製規則

前面的硬骨頭都啃完了,我們來學點輕鬆的緩一緩~

1. 圖元是什麼

  既然 OpenGL 的主要是做用是將圖形渲染到幀緩存當中,那就須要將複雜的物體分解成小的基本單元,這些小單元就是圖元。它包括三種形式:點、線,以及三角形。當它們的分佈密度足夠高時,就能夠表達出2D以及3D物體的形態。OpenGL 中包括了不少渲染這類圖元的函數,這些函數可讓咱們決定圖元在內存中的佈局、渲染的數量和渲染所採起的形式,甚至是同一組圖元在一個函數調用中所複製的數量。

  點、線以及三角形是大部分圖形硬件設備(GPU)都支持直接進行光柵化操做的基礎圖元類型,OpenGL 還支持其餘的圖元類型,例如 Patch 和鄰接圖元,但這些是沒法直接進行光柵化的,今天這裏這介紹前面的三種圖元類型。

2. 有哪些繪製方式

  一個點就是一個四維的齊次座標值。所以,點實際上不存在面積,在 OpenGL 中它是經過顯示屏(或繪製緩存)上的一個四邊形區域來模擬的。當渲染點圖元的時候,OpenGL 會經過一系列光柵化規則來判斷所覆蓋的像素位置,這個用來模擬的四邊形邊長,是經過glPointSize()來設置的,默認大小是1.0,也能夠經過在着色器中寫入值來改變。

線、條帶線與循環線

  獨立的線經過一對頂點來表達,多個頂點也能夠進行連接來表示一系列連線,首尾閉合的叫循環線(line loop),首尾開放的叫條帶線(line strip)。與相似的是,線從原理上來講也不存在面積,因此也須要特殊規則來判斷光柵化會影響哪些像素的值。能夠經過glLineWidth()來設置線段的寬度,默認值是1.0。假設線段的寬度爲 n (n>1),那麼線段將被水平或垂直複製 n 次,複製的方向取決於線段的主延伸方向是 X(水平) 仍是 Y(垂直)。

  簡單歸納線段光柵化的規則diamond exit):假設每一個像素在屏幕上的方形區域中都存在一個菱形,當對一條從點 A 到點 B 的線段進行光柵化時,若該線段穿過了菱形的假想邊,那麼這個像素就應當被影響——除非菱形中包含的正好是點B(即線段的末端點位於菱形內)。因此,此時繼續繪製另外一條從點 B 到點 C 的線段,B點所在的像素也只會更新一次。該規則也是邊緣產生鋸齒的本質緣由——非水平非垂直的斜線段會有一些像素點的菱形假想邊未被連線穿過,這些像素點就不會參與光柵化,進而出現一些像素的缺失,就是咱們看到的鋸齒。關於如何抗鋸齒後面再詳細說。

三角形、條帶與扇面

  三角形之於 OpenGL 初學者而言,就像是每一個程序員最初接觸程序時的 hello world同樣。它是構成一切複雜3D圖形的基本結構,當咱們渲染多個三角形時,每一個三角形與其餘三角形徹底獨立。三角形的渲染是經過三個頂點到屏幕的投影的連線來完成的,若是屏幕像素的採樣值位於投影連線的三角形邊的內側半空間內,那麼它纔會受到光柵化處理,這意味着:

  • 兩個三角形共享了一條邊(即共享了一對頂點),那麼不存在任何採樣值能同時位於這兩個三角形內。
  • 三角形共享邊的光柵化過程不會產生任何裂縫,也不會重複進行繪製。(重複繪製會致使諸如顏色混合計算結果錯誤等問題)

  這對於三角形條帶(triangle strip)或扇面(triangle fan)的光柵化過程很是重要。三角形條帶從第四個頂點開始,會與上一個三角形的後兩個頂點構成新的三角形,以此類推:

三角形條帶
  渲染 扇面時,第一個頂點會做爲一個共享點存在(好比畫圓它就是圓心),它將做爲每個後繼三角形的組成部分,以後每兩個頂點都會與這個共享點組成新的三角形:
  三角形條帶與扇面能夠表達任何複雜程度的凸多邊形性狀。

總結以下:

  圖中 GL_POLYGONGL_QUADS 分別是多邊形和四邊形的連接方式。趕忙結合提供的 案例 ,親自體驗一下每種圖元的使用和適用場景吧。

四. OpenGL 渲染技巧

1. z-fighting

  在渲染立體圖形時,都會開啓深度測試glEnable(GL_DEPTH_TEST),深度 z 的大小決定了物體距離觀察者的遠近,進而影響其在近平面上的投影。對於不透明的物體而言,當投射路徑上有多個表面疊加時,最近的表面纔會被看見。但深度不一樣的表面之間也並非永遠都是這麼相安無事。

  因爲硬件的浮點數精度支持是有限的,所以當投射到同一個點的兩個頂點的 z 值很是接近時,雖然在數學上深度值是不一樣的,但在計算機中可能認爲是相同的,特別是透視變換以後 z 值的精度可能會變低,這個現象對多個像素都有影響,因此會致使顯示結果閃爍交疊的狀況。儘管並不常見,但若是遇到也要記得排查這種可能。

  其實投影變換對每一個方向的座標都會在必定程度上下降精度:距離近平面越遠則精度則越低。舉個通俗的例子:越遠的物體你越看不清細節。

2. 正背面剔除

  在基本圖元的繪製方式中,每一個多邊形都有兩個面:正面和背面,OpenGL 默認多邊形正面的頂點方向是逆時針排列的:glFrontFace(GL_CW)。你也能夠經過glFrontFace(GL_CW)來設置順時針爲正面,你要清楚這一設置的代價。

  像球、環形體和茶壺等都是由方向一致的多邊形組成的,即徹底是逆時針,或者徹底順時針的。而莫比烏斯帶克萊因瓶則不是。假設如今有一個不透明的正方體,構成它表面的多邊形頂點方向都是逆時針的,通過透視投影到近平面上以後,有一部分頂點的方向變成了順時針:沒錯,就是這部分頂點構成了你看不見的那部分——背面,它們永遠都會被正面所遮擋:

  看不見的頂點可用經過設置剔除背面glCullFace(GL_BACK)+開啓面剔除glEnable(GL_CULL_FACE)直接拋棄掉,這能夠極大的提升繪製性能。固然,你徹底能夠剔除正面:GL_FRONT 或者全部多邊形:GL_FRONT_AND_BACK。必要的時候經過glDisable(GL_CULL_FACE)來關閉面剔除,好比繪製透明的物體。

  更多經過glEnable()glDisable()來開啓和關閉的可選參數類型參考這篇

  從更專業的角度來說,判斷多邊形的面是正面仍是背面,是依賴這個多邊形在窗口系統下的面積計算。計算公式及其說明(瞭解便可):

3. 顏色混合

顏色理論

  買過顯示器的你多半見過這個參數:色數,標值一般是 1677萬 或 10.7億,那這個數字表明什麼又是怎麼來的呢?這與計算機圖形學有什麼關係呢?

  絕大多數顯示器使用的都是組合三原色(紅、藍、綠)的方法來構成顏色值,它們構成了顯示器的整個顏色域,咱們稱其爲 RGB 顏色空間,而且使用這三種顏色的組合來表達每一種顏色。咱們能只使用這三種顏色來表達如此龐大範圍的可見光譜的理由是,這三種顏色很是接近於人眼光錐細胞的響應曲線的中心區域。這一點與本篇開篇提到的思想徹底一致。

  OpenGL 中在 RGB 三個份量以外增長了第四個份量 alpha ,即 RGBA 顏色空間。做爲補充 OpenGL 還支持 sRGB 顏色空間。

回答前面的幾個問題。在真實物理世界中,光的頻率和強度都是連續變化的,這使得顏色值的數量等於無窮大。但對於計算機而言,它的幀緩存資源是有限的,因此只能對連續變化的強度進行量子化來限制能顯示的顏色數量。分配給每一個份量用來表示強度變化範圍的大小稱爲像素深度 (bit depth)。例如,每一個顏色份量用 8bit ([0,255])來保存它的強度,那三個顏色份量(alpha 份量除外)一共能夠表示的顏色數量爲 2^8 * 2^8 * 2^8 = 2^24 = 16777216 ≈ 1677萬,10bit 對應的顏色數量就是 10.7億了。如今主流顯示器都是 8bit 的。
  這意味着每一個像素至少存儲三個字節的數據,任何特定類型的顏色緩存記錄到屏幕上每一個像素的數據總量老是相同的。

融混
  若是一個輸入的片元經過了全部相關的片元測試,那麼它就能夠與顏色緩存中當前的值經過某種算法進行合併了。最簡單也是默認的方式,就是直接覆蓋已有的值(不透明或未開啓深度測試的狀況下,這種也不能算是合併)。若是咱們要實現多塊有色玻璃疊加的透明效果,必需要先啓用glEnable(GL_BLEND)顏色混合,而後指定一個顏色混合的算法,好比:glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA),各參數的可用值以下:

融混相關的API使用介紹以及參數說明這裏就不展開了,在後續涉及到的章節中再詳細講解。先結合 案例瞭解簡單的使用便可。

五. 紋理

  關於紋理的概念和基本使用,這一節 講解的已足夠細緻和易懂了,我再強行寫點什麼總有種多此一舉的味道~因此這裏就直接引用啦。固然,最好仍是建議能結合案例源碼看看具體的實現,而後本身動手改一改去驗證本身的理解是否正確。

六. 總結

  此篇提供的兩個案例涉及到的知識點比較多,透徹掌握每個點都不容易,剛開始學習每每最忌諱一頭扎進一個點死鑽,這樣很容易被難點卡住而後半途而廢。因此此篇的主要目的是,先熟悉它們是什麼如何用。我嘗試將它們放到一塊兒,融入實際場景中去描述,一是但願能促進你的理解,二來也能把各個知識點串起來,進而幫你對整個圖形學有個基本的全局觀。

  在全新的領域裏真的處處都是知識盲區。實話說,在寫這篇文章的過程當中,腦子裏充滿了這個表情~

雖然文章更新的速度所以慢了不少,但爲讀者負責的底線必須堅守,痛並快樂着的感受大抵如此吧。但因水平真的有限,仍是不免文中會有表述不夠清晰甚至理解錯誤和錯別字這樣的問題,但願你能見諒並指出問題所在,萬分感謝~

願能幫你多一點收穫。

下面這張圖是去年我在雲南休假時前往玉龍雪山的一張沿途景,再次向你展現了「平行線在無限遠處相交」的問題...哈哈哈~

相關文章
相關標籤/搜索