這是一個嘗試的系列,突發奇想覺得有聲音可能會更有趣,這個系列Blog都會出視訊有聲版。
這個系列主要是為了玩一玩程式碼。
我覺得呢,寫程式是一件很有意思的事情,沒有必要搞得那麼苦大仇深。但是,卻總有那麼一些人、那麼一些資料,非要把寫程式碼搞成一件高山仰止的事情,搞成是非精英屌絲不可完成的任務。搞成是非要你上輩子就註定是個屌絲,這輩子投胎轉世還是個屌絲才能夠從事的職業。
簡單的事情複雜化,具體的東西抽象化,抽象的東西再把它神化。這就是很多資料對你所做的事,他們,只是把你的大腦搞亂,然後讓你覺得,只有成為屌絲,才能寫好程式。
我想搞出一些不一樣的聲音。
視訊地址(Youku) |
快速提高班
現在教大家一些快速提高自己業務(zhuangbi)水平的方法。
要提高自己的業務水平,第一個要訣是:忍。等到別人問你問題,不要主動去說。
問:圖形學中什麼最重要
標準答案:首先得輕嘆一口氣,注意輕嘆一口氣的時機非常重要,在思考兩到三秒後(其實是故作姿態),然後嘆一口氣。
哎,學問中哪來的高低貴賤,你想要了解什麼,你就問吧。
問:什麼是Shader
標準答案:請注意,在回答這種問題的時候,僅僅嘆氣已經不能體現你的業務水平了。一定要微微抬起頭,轉向一個沒有人的方向,盯著天花板或者天空(取決於你所在的環境),眼神空靈,表情空洞。
表現出一副若有所思,若有所悟的樣子,停頓兩三秒種之後,微微嘆一口氣。
哎,shader,不過是管線式渲染體系GPU中的異構子程。
問:那什麼又是異構子程呢
答:異構與同構,乃是哲學中研究主客體關係的一種概念。(其實很簡單,必須要扯上哲學,才能凸顯出業務水平)
被人這樣打破砂鍋問到底,你會不會覺得快要破功了,那,跟著李總一起學點真東西吧。
什麼是真東西
這個問題早有公論:
怎麼學真東西
偉人們告訴我們,從零單排就是最好的方式。
從零單排
接下來是一段歷史介紹,也就是通常所說的尿點。有事情的同學可以去忙了。
很久以前,有一個屌絲在浴缸裡想出了密度這個概念,那時候連阿拉伯數字都還沒有,他叫阿基米德。
不久以前,有一個屌絲在浴缸裡沒事就在想怎麼弄出更好3D效果,那時候連GPU都還沒有,他叫約翰卡馬克。
現在,有一個屌絲,他沒有浴缸,準備陪你一起從零單排3D引擎。現在連一行程式碼都沒有,他叫李總。
很久以前,在3D圖形硬體還沒走走上舞臺的時候,3D畫面,需要卡馬克這樣的人在自己的軟體中開發出3D渲染功能。
所謂渲染,就是突出描寫,對畫畫來說,就是精加工。
卡馬克手裡的工具就是畫素,他寫程式碼把一個個畫素畫成了3D畫面,今天我們叫這個模組:渲染引擎。
軟體中自己實現了渲染引擎,軟渲染,就是這個意思。那個時代,渲染就是指軟渲染。
後來3DFX搞出了Voodoo,GPU才真的普及了,OpenGL、DirectX這一個如雷貫耳的東東才一個個出現,開創了3D硬體加速時代的亂世紛爭。
直到Nvidia吃掉了3Dfx,打敗Trident的TNT、S3的野人,ATI也打響了鐳這個品牌,整個世界彷彿在A卡N卡的光輝下,忘卻了渲染本來就是程式。
從此以後,一談渲染,必定是A卡N卡的硬體加速渲染。而過去的那個渲染,就叫軟渲染。
歷史說到這裡為止。
不積跬步,無以至千里;不積小流,無以成江海。
不學說話,唱不了歌;不學算數,解不了方程。
軟渲染,非學不可
開始開發地球上最簡陋的軟渲染引擎
我們將不使用一個畫素,在100行程式碼內,開發一個基礎的渲染引擎。
首先,新建一個控制檯專案,我們說過的,不用畫素,控制檯程式不能繪圖。
96行,展示了主迴圈,建立了一個六個頂點組成的模型,每幀清除畫面,並繪製模型,這就是一個3D引擎了。
執行起來是這樣的。
3D引擎的本質就是在螢幕上畫三角形,我們做到了,96行代s碼。
在螢幕上畫三角型就叫做光柵化,現在你已經可以深刻的研究,什麼是光柵化。
光柵化就是根據三角形,畫出螢幕上的一個個畫素,我用的方法並不為高效,而只為清晰易懂。
我用了在三角形的AABB碰撞盒範圍內按照字元(畫素)進行掃描的方法,掃描時判斷每個點在不在三角形內。
這裡用了一種叫做同向法的方法來判斷,這個專題不討論這種對業務(zhuangbi)水平沒有幫助的基礎問題,如果有基礎知識的空缺,需要自己搜尋補充一下。
接下去,我們要讓個模型動起來。
在DX OGL的固定管線設計中,設計了三個矩陣去對頂點進行T&L操作,變換與光照。
在可程式設計管線中,就一個矩陣,傳遞給VertexShader,去做變換與光照。
矩陣是可以摸得著,看的見的東西,他並不神祕,接著往下看。
我們也會做一個VertexShader,Shader也並不神祕,往下做你自己就明白了
先來休息一下,回顧一下,把這張圖縮小一點,是不是三角形變的清晰起來了
你可以從這裡取得原始碼。
https://github.com/lightszero/BlockFun/tree/master/win/havefun
稍微研究一下,你會有一種感覺
3D引擎不過如此
空間變換
為了讓模型動起來,我們要對模型做空間變換,聽上去好高大上,其實空間就是座標系。
控制檯螢幕,左上角0,0。右下角80,25,這就是螢幕空間。
而模型為了方便使用,一般會以模型的中點為零點,向三方向擴充套件描述一個模型的座標系。
比如
y軸向上,x軸向右製作模型,讓模型的腳底作為零點,讓模型的高度為10
至少需要這些條件才能描述清楚一個座標系
而模型的零點在他自己的座標系中永遠是零,而當他要在其他座標系中出現的時候,他需要一個位置。
若要問在控制檯螢幕上,我們的模型零點在哪?這就是空間變換。
模型是由頂點描述的,只要變換了每一個頂點,就變換了整個模型。
矩陣
為了對頂點做變換,我們加入了矩陣,用了一個3X4矩陣,這是3D變換中最常用的矩陣,有些數學庫不提供3X4矩陣,用4X4可以相容。
M11 m12 m13 m14
M21 m22 m23 m24
M31 m32 m33 m34
初看矩陣,會覺得這密密麻麻的數字,高深莫測。其實他卻是最簡單質樸,土的掉渣的數學工具。
矩陣就好像計算器,我們只寫了一個頂點變換函式,輸入頂點 xyz 由m11到m13功能決定輸出的x,在加上m14.
矩陣的變換方法,仔細一看是非常簡單的,就是用乘法和加法建立了關係。
對於演算法,計算並不重要,計算所帶來的意義才重要。就像小學生考數學必須手算,後來,考試就可以用計算器。
只要我們理解了演算法的意義所在,知道何時應用一個演算法能產生怎樣的效果。
剩下的事情,交給計算器去做吧。
簡單質樸,土的掉渣的矩陣可以做什麼呢?蔡依林最懂。
旋轉、跳躍、我閉著眼。
把那個行列式填成這樣
1 0 0 0
0 1 0 0
0 0 1 0
你可以試算一下變換函式,隨便輸入一個頂點,輸出結果沒有變化。三點成一面,輸入一個三角形就不會有變化。輸入一個模型,也不會有變化。
你可以從這裡取得原始碼
https://github.com/lightszero/BlockFun/tree/master/win/havefun1
然後執行一下
是不是很有趣呢,旋轉跳躍我閉著眼,用你強大的空間想象(腦補)能力把它想象成師洋在跳舞娘,簡直停不下來啊。
旋轉是通過改行列式的值
M14 M24 是XY的偏移,如果你漸進的改編他們,就可以獲得跳躍的效果
M11 M22 的修改可以產生縮放,我們也讓他動起來,像眯眯眼一樣。
旋轉、跳躍、我閉著眼。
最終就變成了這樣
矩陣建議你自己玩一玩,這裡只要建立起矩陣能幹什麼,怎麼做到的這個基本的概念。
知道矩陣的合成,剩下就可以交給那些數學庫去完成了,沒要必要什麼都自己算。
搞圖形,最重要的是空間想象(腦補)能力
Shader
Shader簡單到什麼程度呢,你如果讀到這裡,在havefun1的原始碼中早就窺透了Shader
所謂Shader,就是把頂點變換,和畫素輸出,兩個步驟,抽象成為了兩個函式,再配合一些引數。
Shader就是程式,還記得我們是在哪裡破功的麼
問:那什麼又是異構子程呢
答:異構與同構,乃是哲學中研究主客體關係的一種概念。(其實很簡單,必須要扯上哲學,才能凸顯出業務水平)
我們這個不足200行的引擎中的Shader 是和引擎一樣用C#編寫的,同構子程式。
而GPU中執行的Shader要用專門的語言編寫,hlsl cg glsl,和引擎編寫的程式不同,異構子程式。
區別,僅僅就是這樣。
經過這一次和李總一起玩程式碼,你再也不會在圖形學業務方面破功(zhuangbi shibai)了。
祝大家業務(zhuangbi)水平蒸蒸日上,源源不絕。
兩條毛腿肩上扛,再會。