Event queue、Arbiter(Loop)、Callback
滑鼠按鍵事件,當按下或放開滑鼠任一個按鍵時觸發,會回傳按鍵編號、狀態以及鼠標位置。
滑鼠移動事件,當按住滑鼠任一按鍵時並移動時觸發,會回傳鼠標位置。
鍵盤事件,當按下鍵盤上任一個按鍵時觸發且滑鼠在視窗內,回傳按鍵編號以及滑鼠位置。
當視窗顯示時、或部分露出、移動視窗都會觸發。
通常會設定清除顏色以及一些緩衝,並開始渲染與繪製物體。
當視窗跳出時、或大小被改變時觸發,會回傳改變後的視窗寬與高。
通常會重設 projection 矩陣、viewport 以及再次呼叫 display event。
顏色緩衝,用來存放要填入顏色的緩衝,分Front與Back兩種,裡面各有4個channel,數值介於0~1之間,分別為RGBA。RGBA各別代表為:Red、Green、Blue和Alpha。每一個大小為8個bits,可以表示種顏色。
深度緩衝,用來儲存物體距離攝影機的距離,數值介於0~1之間,0為最近;反之1為最遠,較近的物體會覆蓋較遠的物體,通常是32位元深。
樣板緩衝,基本上功能類似於遮罩,只有特定區塊可以通過並繪製出來(通過顏色與深度緩衝),其餘部分將不會被繪製。
位移,注意此轉換不是一個縣性轉換。
參數:一個三維的向量,上面的值代表在各xyz軸移動的量。
假設愈要一個物體平移,轉換矩陣為:
平移如果用矩陣來表示就一定要採用齊次坐標(Homogeneous Coordinates)。
旋轉,一般來說都是以原點為中心來選轉,旋轉軸為x、y和z其中一軸,而旋轉方向為逆時針。
該轉換矩陣是正交矩陣(Orthonormal Matrix)。
參數:旋轉中心、旋轉軸、選轉的度數(角度或徑度)。
假設愈要一個物體沿著x軸選轉度,記做,轉換矩陣為:
訣竅:沿著x軸轉動代表x軸不會有任何變動,所以只需要在y與z軸上填入對應的值即可。
如果是沿著z軸選轉度,記做,轉換矩陣為:
訣竅:沿著z軸轉動代表z軸不會有任何變動,所以只需要在x與y軸上填入對應的值即可。
如果是沿著y軸選轉度,記做,轉換矩陣為:
注意:sin與-sin的位置顛倒了。
縮放,小於1代表縮小,大於1代表放大,1代表不變,並以原點為縮放中心。
參數:一個三維的向量,上面的值代表在各xyz軸縮放的倍數。
假設愈要一個物體要縮放,記做,轉換矩陣為:
如果,就代表為Uniform Scaling。
剪切轉換(推移轉換),需要三個參數:要推移的座標(the coordinate to be shear)、推移方向(direction)、以及推移斜率(slope)。
假設愈要沿y軸方向,推移x座標的k倍,記做,轉換矩陣為(Shear X coordinate in Y direction):
訣竅:x = x + ky;
假設愈要沿著z軸方向,推移y座標的k倍,記做,轉換矩陣為(Shear Y coordinate in Z direction):
訣竅:y = y + kz;
假設愈要沿著x軸方向,推移z座標的k倍,記做,轉換矩陣為(Shear Z coordinate in X direction):
訣竅:z = z + kx;
鏡射,基本上就是反射,需要選定一個鏡射軸,而其他兩個軸所形成的平面就會反射兩邊對稱。
假設愈鏡射y軸,此時的鏡射軸為xz平面,轉換矩陣為:
假設愈鏡射z軸,此時的鏡射軸為xy平面,轉換矩陣為:
假設愈鏡射x軸,此時的鏡射軸為yz平面,轉換矩陣為:
意思是經過轉換後,依舊能保持向量加法以及純量乘法的一種轉換,所以必須要滿足以下2個條件:
f(x)為某轉換,u和v為向量,k為純量。
旋轉、縮放、推移、反射都算是線性轉換,而且轉換後的原點依舊是不變的。
對一個向量空間,進行一次線性轉換後並接上一個位移,轉換成另一個空間。
除了要先滿足線性轉換的定義後,還需多滿足一個條件:
映射轉換:加法函數、倍數函數、常數項;線性轉換:加法函數、倍數函數。
映射轉換要使用齊次坐標(Homogeneous Coordinates),因為位移的關係。
指的是物體的大小形狀不會被改變,但位置與方向會被改變。
所以泛指平移+旋轉,也是我們常說的6個自由度(Degrees of freedom),分別為:
的反矩陣就是 。
的反矩陣就是 ,其他依此類推。
的反矩陣就是 ,其他依此類推。
的反矩陣就是 ,其他依此類推。
鏡射矩陣的反矩陣依舊不變,所以執行兩次就是會相互抵銷,它是一個對偶轉換(Dual Transformation)。
正規化後:
其中
正規化:
求出攝影機之y正軸向量
寫入View Matrix
投影矩陣的效果:
詳情介紹可看這篇:Projection Matrix。
透視矩陣為:
而其深度資訊(z)從眼睛坐標系轉換至投影坐標系的公式為,此轉換是非線性的:
原點在視窗左下角,為(0,0)。
環境光。
漫射,光的強度取決於【物體到光源的方向】和【物體表面的法向量】之間的 cos 夾角,當兩者之間角度為時,亮度最強為1;反之角度為時,亮度最弱為0。
這邊的 normal 和 lightDir 都必須要正規化,計算出來的才會是 cos 角度值哦!
向量點乘公式:
高光,可以看出光的強度取決於【物體到眼睛的方向】和【光反射的方向】之間的的夾角,以及【物體的 shininess 程度】。
注意 lightDir 此向量是由物體指向光源方向,在計算 reflectDir 時必須要先將 lightDir 取反(變成從光源指向物體),這樣使用 reflect() 時計算出來的 reflectDir 方向才會正確。
此計算方式是使用 Snell's law,入射角等於反射角。
如果是使用 Blinn-Phong 光照模型的話,高光的計算方式為:
光衰弱,光的衰弱跟距離成反比,通常表示:。
但這通常會太暗,只比較適合晚上或水下場景。
比較完整的衰弱公式為:,其中C通常都是固定為1。
光可以分為:Direcitonal Light、Point Light、Spot Light。
在 Viewport 之後就會進行 Polygon Filling 和 Shading。
找出多邊形的像素有哪些:Resterization(柵格化)。
計算像素的顏色、光與暗等。
材質的解析度【大於】多邊形的解析度,有 Nearest 和 Linear(Box Fliter)兩種模式。
材質的解析度【小於】多邊形的解析度,有 Nearest interpolation 和 Linear interpolation 兩種模式。
用 Perspective 投影矩陣的 Depth Cue 的效果為:
如果用 Orthogonal 投影矩陣是無法令人產生 Depth Cue 的。
使用 Fog 效果會讓越遠的物體會越模糊不清,這可以提升 Depth Cue。
物體越遠看起來越暗,顏色越不清楚,漸漸淡入霧中。
其中,代表該Pixel的顏色,則是霧的顏色。
是霧的強度參數,而計算方式根據模式不同有不同的計算:
其中的 是指每一個單位距離中霧的密度。
但是注意,這邊的 是使用 Depth Buffer 中的沒錯,但這樣是線性內插,並不準確。
所以可以用另一個方法:Range Based,距離看的是眼睛看過去的總長度(使用length()
)。
OpenGL