--- tags: CCU, 計算攝影學 --- # 2020計算攝影學整理筆記(上) [2020計算攝影學整理筆記(下)](https://hackmd.io/@bshG7JUyR_29IAVeaT9ZDA/Bk3fe9baP) --- [Course Works 課業倉儲](https://www.cs.ccu.edu.tw/~damon/secure/course-wk.html) [Discussion Board 課程討論區](https://140.123.101.97/login.htm) :::danger 每天記得看一次課程討論區有沒有最新的資訊 ::: + 目錄: - [1. Overview](#Overview) - [2. OpenGL](#OpenGL) - [3. Scope](#Scope) - [4. 2D coordinate](#2D_coordinate) - [5. 2D Transformation](#2D_Transformation) - [6. Camera](#Camera) - [7. 3D View](#3D_View) - [8. 3D Transformation](#3D_Trans) - [9. Color](#Color) - [10. Lighting and Shading](#Lighting_and_Shading) - [11. Texture](#Texture) - [13. Alias](#Alias) ------------------------ # Overview ## Grading :::danger 評分標準可能會變動 ::: | 評分標準 | 比重 | | ----------------- |:----------------------- | | Laboratories (4~7) | 25% | | Midterm | 33% | | Final exam | 20% | | Final project / PowerPoint slides | 12% | | Punctuality, attendance, <br> and participation in discussions | 10% | :::warning 計算攝影學上課不定期點名 ::: --- # OpenGL ## OpenGL簡介 openGL是一個 ==圖形渲染== (graphics rendering)的API openGL中的每個視窗都是 ==獨立作業== 的 OpenGL not object-oriented(==非物件到導向==) OpenGL can render Geometric primitives(幾何圖元),Bitmaps and images(位圖和圖像). ## Event Queue ![](https://i.imgur.com/yQqeXzO.png =600x) 事件觸發時會把事件送到Event Queue**順序執行** :::warning 需要等前一個事件結束下一個事件才會被處理 ::: ## Object Definition Modes ![](https://i.imgur.com/nPqb3hb.png =600x) ## Command Formats ![](https://i.imgur.com/0wsnSS3.png =600x) ## Callback Function Callbacks: most of window-based programs are event-driven, which means do nothing until an event happens, and then do the specific thing. (多數基於窗口的程序都是事件驅動的,這意味著在事件發生之前不執行任何操作) 1. Resizing(**Reshape**). 2. Rendering(**Display**). 3. Input device: keyboard, mouse, etc. ```cpp= //如何註冊事件 glutDisplayFunc(myDisplay);// register redraw function glutReshapeFunc(Reshape);// register resize function glutMouseFunc(myMouse);// register mouse action function glutKeyboardFunc(myKeyboard);// register keyboard action func ``` ## Program Skeleton ```cpp= glutInitDisplay(GLUT_RGB|GLUT_DOUBLE);//使用2個buffer glutInitWindowSize(300, 400);//視窗大小 glutInitWindowPosition(100,100)//視窗位置 glutCreateWindow("Example");//新增視窗,參數為視窗名稱 glutDisplayFunc(Display);//註冊 display callback function glutMouseFunc(myMouse);//註冊 mouse callback function glutMainLoop();// process events ``` ```cpp= glutPostRedisplay();//對視窗更新畫面 ``` :::info Display mode: in **double-buffing**, the **front buffer** is the one which is displayed. You draw to the other one called the **back buffer**. To update the image, simply **swap** the two buffers. <br> 翻譯蒟蒻:使用2個buffer,你在畫時是畫在後端的buffer,當你要更新影像時只要把兩個buffer交換就行了。如果是用single,有可能在畫的時候會看起來像是 **慢慢渲染** 的樣子。 呼叫 **glutSwapBuffers();** 做兩個buffer的交換 ::: --- # Scope ~~垃圾章節~~ **Tone mapping**: HDR影像一般指色彩強度超過 8-bit [0~255] 範圍的影像,而 tone mapping 則是將其動態範圍壓縮回 8-bit 的過程,才能使其顯示在螢幕上。 **Shadow Editing (編輯陰影)** **Color2Gray (轉灰階)** **Filter**: De-noise (去雜訊)、De-Blur (去模糊) **Superresolution**: 從低分辨率獲取清晰的高分辨率圖像。 **Matting**: 照片合成(把人頭放到其他圖上之類的) **Background Replacement**:去背景 **High Dynamic Range Imaging(HDR)**:成像的目的就是要正確地表示真實世界中從太陽光直射到最暗的陰影這樣大的範圍亮度,後來開發出一些從不同曝光範圍相片中生成高動態範圍圖像的方法。 **Gradient image manipulation**: 以圖像梯度而不是像素級別進行操作。(減少合成後的詭異感) **Poisson Editing**: 可以在一定範圍內影響紋理、光罩、特定區域顏色。(合成的一種方法) **Texture transfer(Style transfer)**: 紋理轉移、風格合成 **Hybrid Images**: 混和圖象(人形貓頭) --- # 2D_coordinate ## Screen Coordinate System **視窗座標系統** 原點(0,0)在==左下角== 水平為X軸,垂直為Y軸 This coordinate system goes with the display window. ![](https://i.imgur.com/ElcDgsz.png) ## Viewport 在視窗中的矩形區域顯示OpenGL object: ```cpp= glViewport(int left, int bottom, int right-left,int top-bottom); //設定viewport的起點(left,bottom) //再設定在視窗中顯示多高多寬 ``` :::warning Call this function **before** glBegin()and glEnd(). ::: :::warning 如果viewport長寬比跟world window不一樣的話 畫面可能會**扭曲(distort)** ::: ## World Window **世界座標** 如何設定World Window: ```cpp= gluOrtho2D(left, right, bottom, top); ``` :::warning Before calling gluOrtho2D(),you need to have it preceded by two setup functions glMatrixMode(GL_MODELVIEW); glLoadIdentity(); ::: :::info **Concept of world window** 假設一段程式碼: glutInitWindowSize(1000, 1000); gluOrtho2D(0, 500, 0, 600); glViewport(0, 0, 100, 200); 你openGL畫面x的範圍就是0 ~ 500,y的範圍就是0 ~ 600 在你openGL畫面裡面的世界座標就是這樣的大小 如果你畫一個點在(550,600)的話,則這個點就不會顯示出來 因為這個點已經超出你openGL畫面的世界座標了 viewport則是把你的畫面顯示在你的視窗上 而viewport可以做的事就是決定顯示在視窗的哪裡、顯示的長跟寬 上面程式碼的viewport是指從視窗的(0,0)開始顯示畫面 顯示出來的畫面長寬為(100,200),會把你整個openGL畫面扭曲 ::: ### How to set up an appropriate world window automatically? 如何設定一個適當的world window? :::success The basic idea is to see all the objects in the world. Find the maximum world coordinate extent that will cover the entire scene. 設定一個世界座標能夠包含畫面中所有的物體或景色 ::: ### How to zoom-in the picture? :::success Making the window smaller is much like zooming-in on the object with a camera. 當你world window設定的範圍越來越小時,看起來就像在做zoom in ::: ## Modelview Transformations :::danger 重要,必會(後面章節會講得更清楚) ::: ```cpp= glPushMatrix();// save current matrix. glTranslatef(x, y, 0);// apply translation. glRotatef(10,0,0,1);// apply rotation. glRectf(-1,-1,1,1);// draw rect at the origin. glPopMatrix();// restore the old matrix. ``` glPushMatrix()會把你目前的矩陣存起來 而glPopMatrix()會恢復你之前存起來的矩陣 :::info 這兩個function都是以 **Stack(堆疊)** 做運算的 Stack特性: 說後進先出(LIFO,Last In First Out)或 先進後出(FILO, First In Last Out)都可以 ![](https://i.imgur.com/U3UhFRw.png) ::: :::warning openGL裡的平移、縮放、旋轉等等矩陣運算的function都沒有數字 (像之前的glColor3f這種的function) 因為這裡的這些矩陣運算一律都以三維空間做矩陣運算 沒有區分是二維的旋轉或是三維的旋轉(and so on) ::: --- # 2D_Transformation Given a 2D object, transformation is to change the object’s: 1. Position (**translation**) 2. Size (**scaling**) 3. Orientation (**rotation**) 4. Shapes (**shear**) ## Translation 平移矩陣: ![](https://i.imgur.com/cV1u3hn.png =500x) ## Rotation 以==原點為中心==旋轉 ![](https://i.imgur.com/gKgjuKh.png =500x) 旋轉矩陣: ![](https://i.imgur.com/35vdyif.png =500x) :::warning 角度為正是逆時針旋轉 角度為負是順時針旋轉 ::: ## Scaling ![](https://i.imgur.com/Q8a4hoO.png) :::warning Not only the object size is changed, it is also being **repositioned**. 除了縮放,他也位移了 **因為Scale是直接乘積上去** 例如: glScalef(2,1,1); glVertex3f(1,1,0); glVertex3f(2,1,0); glVertex3f(1,2,0); glVertex3f(2,2,0); 他會對這四個點的x都乘以2 四個點的y都乘以1,and so on. ::: ![](https://i.imgur.com/MRZTZfq.png =500x) ## Shearing ![](https://i.imgur.com/LXiNeow.png) ![](https://i.imgur.com/gZ6BPQq.png) ![](https://i.imgur.com/m4FN2wF.png) ![](https://i.imgur.com/pgCE0cr.png) :::info A 2D rotation is three shears. Shearing will not change the area of the object. Any 2D shearing can be done by a rotation, followed by a scaling, and followed by a rotation. 2D的旋轉是做3次shear達成的 shearing不會改變面積 ::: ## 以任意點為中心進行縮放/旋轉 :::warning 先**平移回原點**再做縮放/旋轉,然後再**平移回去**原本的位置 如果不先平移回原點再做縮放/旋轉會比較麻煩 T(px, py) R(θ) T(-px, -py) * P ![](https://i.imgur.com/NA8dRXc.png) ::: ## Affine Transformation is a ==linear combination== of the original point P. Translation, scaling, rotation, shearing are all affine transformation :::info Affine matrix= translation x shearing x scaling x rotation ::: ## Composing Transformation M3 M2 M1 矩陣會先相乘變成一個矩陣(M) ![](https://i.imgur.com/6efVHSS.png =600x) :::warning 矩陣乘法符合**結合律(associative)** 但只有特定條件下才符合**交換律(commutative)** ![](https://i.imgur.com/EJcB4V4.png =500x) ::: ```cpp= glLoadIdentity();//將當下的坐標系復原到原點(螢幕中心) [1,0,0] [0,1,0] [0,0,1] ``` :::danger You need to specify the transformation in an **opposite order(相反順序)**. 當要寫程式時,矩陣運算順序需要**倒過來寫** ex:要對某個物體先做縮放再位移時 ```cpp= glTranslatef(x,y,z); glScalef(a,b,c); //矩陣運算順序倒著寫 drawObject(); ``` ::: --- # Camera ## Pinhole camera model 1. Captures pencil of rays – all rays through a single point. 2. The point is called Center of Projection (COP). 3. Effective focal length f is distance from COP to Image Plane. ### 缺點: 1. 針孔尺寸必須“很小”才能獲得清晰的圖像。 2. 由於使針孔尺寸變小,因此像平面接收到的光更少,需要更長的曝光時間。 3. 如果針孔與入射光的波長相當,則衍射效應會使圖像模糊。 ## Dimensionality Reduction Machine (3D to 2D)降維 從三維空間降維到二維平面的話,會有一些資訊遺失 1. 角度 2. 距離 ## Overview 鏡片跟視角會決定==透視圖== 光圈跟快門速度會決定==曝光度== 光圈跟其他因素會決定==景深== 膠片或傳感器紀錄圖像 ## Shrinking the aperture (縮小光圈) 小光圈會有清晰的影像,但光圈==不能太小== 光圈太小 ->入射光少 ->曝光時間長 :::warning 太小的光圈會造成[衍射(繞射)現象(Diffraction effects)](https://zh.wikipedia.org/wiki/%E8%A1%8D%E5%B0%84) ::: ![](https://i.imgur.com/DsBbUGY.png =400x ) ### Sharpest image(最清晰的影像) 公式: ![](https://i.imgur.com/ulsFvRu.png) d: 光圈直徑 f: 焦距(focal length) λ: 光的波長 ## Focal length: pinhole optics :::warning 當焦距變2倍時 投影出來的物體大小也會變2倍 但聚光量會變成原本的**1/4** depth of field是circle of confusion小於人眼分辨率的區域。 ::: 物距倒數 + 像距倒數 = 焦距倒數 ![](https://i.imgur.com/5UNhaGD.png) ![](https://i.imgur.com/tiKgbZ5.png =600x) 通過對稱性,在焦距上的物體要求膠片(film)處於無限遠 ## CDD v.s CMOS CCD不太容易受到噪聲的影響。 CMOS更靈活,更便宜,功耗更低。 ## Field of view 焦距大=>視野小=>zoom in 焦距小=>視野大=>zoom out Field of View (**Zoom**) = ==Cropping== ## Depth of field 更改光圈大小會影響景深,光圈越大->景深越小 ## Circle of confusion 點光源在光軸上前後移動,會在成像平面上形成一個圓,只要足夠小則不影響成像,過大則會模糊,頻界點就叫Circle of confusion ## Aperture (光圈) 光圈是鏡頭開孔的直徑,通常由f-stop,f / D(焦距的一部分)指定。 – f/2.0 on a 50mm means that the aperture is 25mm. – f/2.0 on a 100mm means that the aperture is 50mm. ## Exposure 主要參數:光圈、快門速度(速度太慢會有==motion blur==、速度快可以定格) ## Field sequential 場色序法(Field sequential),為一種==不需使用彩色濾光片==的顯示。利用時序顯示紅、綠、藍等子畫面,藉由==人眼視覺暫留==,在視網膜上透過時間混色的方法呈現全彩的影像。 ## Color filter array (CFA) 全彩影像通常由三個顏色所組成,最常使用到的是紅、綠、藍三色。但為了成本的考量,大多數的數位相機在單一像素位置上只會有單一顏色感應器。最普遍使用到的色彩濾波矩陣為Bayer CFA ## Lens related issues ### Vignetting 漸暈 指圖像的外圍部分的亮度或飽和度比中心區域低,通常是因為相機的設定和鏡頭的限制因素等 ### Chromatic Abberation 色差 ==(考古)色差是由鏡頭縮短引起的(X)== 鏡片對於不同波長具有不同的折射率,使用兩塊或更多塊具有不同折射率的玻璃的特殊透鏡系統可以減少或消除此問題。 ![](https://i.imgur.com/85xRiq8.png =300x)![](https://i.imgur.com/Fr2cdg0.png =300x) ### Distortion(扭曲) –由不完善的鏡片引起 –對於穿過鏡頭邊緣的光線,偏差最明顯 ![](https://i.imgur.com/t5Zkdv9.png) #### Radial Distortion 直線圍繞圖像中心彎曲 ### Interlacing (隔行掃描) ![](https://i.imgur.com/VmuU1zs.png) --- # 3D_View ## Modeling Transformation 可以將變換視為==移動坐標系== ## Viewing Transformation Camera (eye) position : ex, ey, xz: 觀看者(相機)的位置 Center of interest (coi) : cx, cy, cz: 觀看者(相機)看的方向(點) Orientation View-up vector : upx, upy, upz: 觀看者(相機)頭頂的方向 第一組座標就是腦袋的位置 第二組座標就是眼睛看的物體的位置 第三組座標就是頭頂朝向的方向(因為你可以歪著頭看同一個物體)。 :::warning 向量(upx,upy,upz)不一定要跟viewing vector (cx,cy,cz) 垂直,但**不能平行** ::: 如何設定: ```cpp= gluLookAt(ex,ey,ez,cx,cy,cz,upx,upy,upz) ``` ## Prospective Projection(透視投影) 離眼睛==越近==的物品越大、符合現實情況 ## Orthographic Projection(正交投影) 距離==不影響==物品大小、投影中心==無限遠==、Projection calculation 僅去除==Z坐標==。 ## View Frustum (Near and Far Clipping Planes) ![](https://i.imgur.com/ngTXO8B.png) --- ![](https://i.imgur.com/l8ipuSK.png) **在frustum(視錐)外的區域就看不到了** --- ![](https://i.imgur.com/SmcLjSt.png) ![](https://i.imgur.com/R70YScz.png) aspect = h / w , 用於計算窗口寬度 glFrustum 可以跟 gluPerspective 互換 ![](https://i.imgur.com/RuDTEYq.png) ![](https://i.imgur.com/CdKfk3p.png) ## GLU/GLUT provides very simple object glutWireCone、gluCylinder、glutWireCube、glutWireTeapot --- # 3D_Trans :::danger 重點章節 ::: ## Hierarchical Representation(分層表示) 可以以分層的方式表示對象,對象的位置和方向會受到其父節點,祖父母節點,祖父母/祖父母節點的影響。 ![](https://i.imgur.com/H6GKdbw.png =300x) This hierarchical representation is referred to as ==scene graph==. :::success 可以參考資料結構 [Tree](http://alrightchiu.github.io/SecondRound/treeshu-introjian-jie.html) ::: ## Absolute Transformation each part of the object is transformed ==independently== relative to the origin. 每個部分都是獨立做矩陣轉換 ```cpp= //參考程式碼 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glPushMatrix(); glTranslatef(5, 0, 0); Draw_Base(); glPopMatrix(); glPushMatrix(); glTranslatef(5, 0, 0); glRotatef(-90, 0, 1, 0); Draw_Lower_Arm(); glPopMatrix(); glPushMatrix(); glTranslatef(5, 0, 0); glRotatef(-90, 0, 1, 0); Draw_Upper_Arm(); glPopMatrix(); glPushMatrix(); glTranslatef(5, 0, 0); glRotatef(-90, 0, 1, 0); Draw_Hammer(); glPopMatrix(); ``` ## Relative Transformation each part of the object is transformed ==relative to its parent== part. 每個部份的轉換會跟他的parent有關 Hammer的parent -> Upper arm Upper arm的parent -> Lower arm Lower arm的parent -> Base(Base屬於root,意即他沒有parent) ```cpp= glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(5, 0, 0); Draw_Base(); glRotatef(-90, 0, 1, 0); Draw_Lower_Arm(); Draw_Upper_Arm(); Draw_Hammer(); ``` ### Another Example ![](https://i.imgur.com/zmCvuNg.png) ![](https://i.imgur.com/1N5Ci2P.png =300x)![](https://i.imgur.com/P0TYCCm.png =300x) **(右上圖:有顏色的線代表矩陣轉換會影響到的區塊)** :::warning 這些轉換是以DFS的順序執行,換個想法就是 Base(root) --> Left hammer --> Right hammer(leaf) 從relative transformation的角度來看 雖然Right Hammer轉了-75度 但Left Hammer跟Right Hammer都轉了75度 所以Right Hammer等於**沒轉** ::: :::success 解法一:glPushMatrix() & glPopMatrix() 解法二:Right Hammer 轉 -150度 (我猜的) ::: ![](https://i.imgur.com/nSAobiT.png) :::danger 重要,必會 ![](https://i.imgur.com/DxM9fJ7.png) ::: ## Homogeneous coordinates ![](https://i.imgur.com/H0x4Ql0.png) ## Right-Hand Coordinate System ![](https://i.imgur.com/QqSOsYZ.png) --- # Color The frequency, ζ,of light determines its “color” 光的頻率決定顏色 :::info **波長(Wavelength)** 以及 **能量(Energy)** 也有關係 ::: Describe incoming light by a ==spectrum==: 1. 每種頻率光的強度 2. 強度圖 vs. 頻率 :::info 我們只在乎可見光: 頻率大多在**700nm ~ 400nm**之間 ![](https://i.imgur.com/bGbBsX1.png =250x) ::: | | 椎狀細胞(Cone Cell) | 桿狀細胞(Rod Cell) | |--- | --- |--- | | 辨色能力 | 好 |無法辨色| | 感光度 | 差 | 高 | |其他 | 無 | 分辨細節能力低 | |數量|少|多| ## How to Represent Color ### RGB Color Model Representing color as a ==linear combination== of <font color=#FF0000>red</font>, <font color=#00FF00>green</font>, and <font color=#0000FF>blue</font> is related to cones. ![](https://i.imgur.com/2riFaQW.png) 三個顏色的範圍都介於==0~255==之間 :::info 缺點: Strongly correlated channels 受channel影響很大 Non-perceptual 非感知的 ::: ### HSV Color Model 1. Hue(色相): 0 ~ 360度,各種顏色 2. Saturation(飽和度): 顏色的純度(0% ~ 100%),離中心點越遠==純度越高== 3. Value(or Luminance)(明度、亮度): ~~就亮度~~(0% ~ 100%) :::warning 2017考古 ![](https://i.imgur.com/AXUsWTN.png) ::: ![](https://i.imgur.com/neKZ82B.png) ## Color Deficiency(色差) 有些人會缺少其中一種感知能力,又以缺少==分辨紅綠==感知功能的最多(色盲) 其他缺陷:Anomalous trichromacy, Achromatopsia色盲, Macular degeneration黃斑點退化 --- # Lighting_and_Shading ## Illumination (Lighting) 對光與表面點的互相作用進行建模,以確定其==最終顏色和亮度== (考古) Modeling transformation -> clipping -> window to viewport mapping -> rasterization ### 照明模型通常考慮: – **Light attributes** : 燈光強度,顏色,位置,方向,形狀 – **Object surface attributes** : 顏色,反射率,透明度 – **Interaction among lights and objects** : 燈光和物體的相互作用 ### Basic Light Sources: **光強度可以獨立於或取決於對象與光源之間的距離。** ![](https://i.imgur.com/kE6pTjG.png) ### 衰減(Attenuation) 光會受到衰減,即隨著距光源的距離增加,照明強度會降低,物理學說光強度隨距離平方成反比。 **OpenGL還沒實現衰減->計算要求高** ### Local Illumination Model (局部照明) 僅考慮光線,觀察者位置和物體的材料屬性(==OpenGL使用這種==) ==不處理==來自其他物體的間接作用(ex.光線從某一物體反射至另一物體) ==不處理==會反射or折射的物體(ex.金屬球、玻璃) ### Global Illumination Model 考慮場景中所有表面的光的交互作用(ex.ray tracing) :::warning 計算複雜度極高 為O($n^n$) ::: ![](https://i.imgur.com/yE81gre.png) ### Point Emission -OpenGL假定所有光源都是==點==,且所有表面皆為==多邊形==。 -點發射僅影響光源直接可見的點。 -OpenGL只須測試所有面是朝光還是背光(某些情況是錯的)。 ### Light Sources at Infinity 許多涉及光源的計算都需要計算表面法線和光源位置之間的角度。 如果光源在==無限遠處==,則單個多邊形面片上的所有點都具有==相同==的角度。 ### Simple Local Illumination OpenGL只考慮**Ambient(環境)**、**Diffuse(漫射)**、**Specular(鏡面)** 3種類型的光來計算最終照明 **Final illumination of a point (vertex) = Ambient + Diffuse + Specular.** ## Light Contribution ### Ambient Light Contribution (背景光:被環境散射的光) ~~global illumination的非常簡單的近似值~~ 可以簡單的近似於全局照明(global illumination) 沒有方向,所有表面和方向都能被均等的照亮。 每個光源都有一個環境光量(I),不同objects可以反射不同的環境光量(Ka) ==Ambient = I * Ka== ### Diffuse Light (漫射光) ### Contribution 表面從光源接收並在所有方向上==均等反射==的照明,==眼睛在哪都一樣==。 由foam rubber等沒有光澤的光滑物產生 ![](https://i.imgur.com/HUiLNG4.png) ### Calculation Lambert’s law: the radiant energy D that a small surface patch receives from a light source is: D = I x cos (θ) I: 光線強度 θ:光線跟法向量的夾角 ![](https://i.imgur.com/Q9vndLl.png) Diffuse = Kd x I x cos (θ) (不同Object可以反射不同數量的反射光) Kd: 漫射光的反射係數 ### Specular Light (鏡面光) ### Contribution Object上的亮點,集中區域中入射光的全反射,亮點會出現在光滑的發光表面上。 ![](https://i.imgur.com/MqUVyZ7.png) ### Calculation 若為理想表面,則眼睛從P點看到的亮點是唯一位置,φ越小看到越多鏡面光 ![](https://i.imgur.com/fbFK8jN.png) ![](https://i.imgur.com/RETx1IW.png) ![](https://i.imgur.com/wNdPlKe.png =300x) *n越大,cos值越小,亮度越小* Ks:鏡面反射係數。 N:P處的表面法線。 I:光強度。 Φ:V和R之間的角度。 n: n越大,Φ越小,在物體上的亮度區塊也越小 ## Diffuse Ligh & Specular Light ==Illumination from a light: Illum (2017考古) = Ambient + Diffuse + Specular = Ka x I + Kd x I x (N∙L) + Ks x I x (R∙V)^n== If there are N lights, Total illumination for a point P = ∑n(Illum). ### use diagrams and equation to explain the D / S term in the equation ![](https://i.imgur.com/j7893HJ.png) ### Setting up OpenGL lighting: – Light properties.(燈光屬性) – Enable/Disable lighting.(啟用/禁用照明) – Surface material properties.(表面材料特性) – Provide correct surface normals.(提供正確表面法線) – Light model properties.(燈光模型屬性) ```cpp= GLfloat light_ambient[] = {0.0, 0.0, 0.0, 1.0};// black GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0}; // white GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};// white GLfloat light_position[] = {0.0, 0.0, 1.0, 1.0}; glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv(GL_LIGHT0, GL_POSITION, light_position); ``` Determined by the light positions you provide: – w = 0: infinite light source (faster).(去除除0的問題) – w != 0: point light –> position = (x/w, y/w, z/w) ```cpp= GLfloat light_position[] = {x, y, z, w}; glLightfv(GL_LIGHT0, GL_POSITION, light_position); ``` ```cpp= glEnable(GL_LIGHTING); glDisable(GL_LIGHTING); glEnable(GL_LIGHTn)//啟用第幾個光源 //GL_LIGHT0~7,OpenGL共有8個光源 ``` #### Material Properties 設定材質的顏色跟表面特性 ```cpp= GLfloat mat_amb_diff[] = {1.0, 0.5, 0.8, 1.0}; GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0}; GLfloat shininess[] = {5.0};//(range: dull 0 –very shiny 128) glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_amb_diff); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_speacular); glMaterialfv(GL_FRONT, GL_SHININESS, shininess); ``` #### Global Light Properties ```cpp= //two-side lighting glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); //global ambient color glLightModelfv(GL_LIGHT_MODEL_AMBIENT, value);//value = (red, green, blue, 1.0); ``` #### Surface Normals 畫每個多邊形都需要提供一個法向量才能計算光 :::info glEnable(GL_NORMALIZE)可以幫你把所有的法向量變成單位法向量 ::: ## Lighting Revisit :::warning ![](https://i.imgur.com/S86Zo4U.png) ::: ## Polygon Shading Models ### Flat shading (glShadeModel(GL_FLAT)) 僅使用一個頂點法線和材質屬性來計算多邊形的顏色,==計算快速== 在==多邊形夠小、光源、眼睛夠遠==時使用 Mach band effect : 人眼會加劇邊界處的不連貫性 ![](https://i.imgur.com/QjSrnAf.png) ![](https://i.imgur.com/UhL6i0Y.png) ### Smooth Shading 用內插法去計算內部顏色 修復 mach band effect–消除邊緣不連續性。 計算照明以在每個面上獲得更多點。 ![](https://i.imgur.com/pixBVmZ.png) #### Two popular methods: – Gouraud shading (used by OpenGL). – Phong shading (better specular light, not supported by OpenGL). ![](https://i.imgur.com/P3e7W8K.png) ```cpp= glShadeModel(GL_SMOOTH)//設定Ground Shading ``` #### Gouraud Shading 先計算三角形每個頂點的光照,再通過線性插值計算三角形區域中其它像素的顏色。 ![](https://i.imgur.com/ynniVj9.png) 多邊形內部的照明可能不正確(在正常情況下會是某個地方特亮,但使用Gouraud會導致==內部點失真==) #### Phong Shading 所有點取法向量->和頂點做內插->再做打光計算 ![](https://i.imgur.com/NEp8bst.png) 計算速度==很慢== --- # Texture **一種增加表面細節的方法** ## Texture Mapping(紋理貼圖) **方法一**:新增額外的多邊形去形成細節 :::warning 此方法會**增加景象複雜度**而且會**降低渲染速度** 有些細節也很難去塑造出來 ::: **方法二** 在表面使用貼圖 :::info Complexity of images does not affect the complexity of geometry processing (transformation, clipping...) 圖片複雜度不影響幾何處理的複雜度 ::: ![](https://i.imgur.com/fejI1Ji.png) ## Texture Representation 1. Bitmap(pixel map) textures (==supported by OpenGL==). 2. Procedural textures (其他進階的渲染程式,這裡不談) ### Bitmap texture 1. 2D影像: 使用==array==來表示 (型式: texture[height][width]) 2. 每個Pixel(或稱texel)都有一個唯一的座標(s,t) 3. s跟t通常都會被正規化到==0~1==之間 ## Texture Value Lookup ![](https://i.imgur.com/2aVpIn0.png) :::info Nearest nighbor: 從四個點中使用離他最近點的顏色值 Linear Interpolation: [線性插值](https://zh.wikipedia.org/wiki/%E7%BA%BF%E6%80%A7%E6%8F%92%E5%80%BC) ::: ## Map Textures to Surfaces 要把texture貼到多邊形時要指定多邊形的==每個角落座標== (多邊形的大小不限) :::info ![](https://i.imgur.com/2aHrdTF.png =300x) rasterization: 從一張圖片轉換為二維影像(pixels)的過程 rasterization 會根據多邊形頂點的位置,來確定需要多少個pixel才能構成這個多邊形,以及每個pixel的座標、座標的顏色(插值)等等資訊,最後顯示出來。 ::: Steps on OpenGL: 1. 指定texture: 讀或產生圖片然後指定為texture 2. 指定texture mapping 參數: warpping,filtering,... 3. 開啟紋理貼圖 4. 指定texure座標 5. 關閉紋理貼圖(不需要再用到的話) ```cpp= glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 64, 64, GL_RGB, GL_UNSIGNED_BYTE, myImage); //myImageis a 2D array: GLubyte myImage[64][64][3]; ``` :::warning texure的影像長寬必須是**2的指數倍(power of 2)** <br> 解決方法一: 邊緣補0 解決方法二: gluScaleImage() ::: ## Texture Mapping Parameters 如果texture座標超過[0,1]呢? <br> ![](https://i.imgur.com/E2vkma9.png) <br> ```cpp= glTexParameteri(GL_TEXTAURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP). glTexParameteri(GL_TEXTAURE_2D,GL_TEXTURE_WRAP_S, GL_Repeat). ``` ![](https://i.imgur.com/NhwnmHS.png) <br> 當texture被map到多邊形時可能會放大或縮小: **使用==Filtering==** <br> ![](https://i.imgur.com/hmw8jHt.png) ```cpp= glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); ``` ## Texture Color Blending(顏色調和) 決定如何結合texture顏色跟物體顏色 1. GL_MODULATE: 兩個顏色相乘 2. GL_BLEND: 兩個顏色的線性組合(?) 3. GL_REPLACE: texture顏色取代物體顏色 ```cpp= glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); ``` ## Enable (Disable) Textures ```cpp= glEnable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D); ``` :::warning 當你要畫的圖形沒有要用到texture mapping時記得disable ::: --- # Alias 錯誤信號來自==信號頻率==和==採樣頻率==之間的誤差(ex. Jagged edges、False texture patterns) 將圖像數位化的兩個步驟: sampling(採樣) and reconstruction or filtering(重構). ![](https://i.imgur.com/NNvDFLU.png) ![](https://i.imgur.com/YCzAg9y.png) ![](https://i.imgur.com/mRtvzE6.png) ==採樣頻率過低== <br> ![](https://i.imgur.com/zAbrAbq.png) ### 正確採樣頻率 必須至少是採樣信號最大頻率的==兩倍==,(但可能遇到最大信號頻率的大小是無限大,所以不能以離散方式完全採樣銳利邊緣) ## Reconstruction Filters ![](https://i.imgur.com/7A1ngBi.png) ### Box Filter 非常簡單,但不是很好–產生的信號是==階梯且不連續==。 ### Tent (Triangle) Filter 基於線性插值–更好,構造的信號是連續的,但==仍不平滑==。 ### Sinc Filter ==理想的低通濾波器==–獲得連續信號。 但是計算機圖形不能使用連續信號,可以將連續信號重新採樣為另一個大小,即放大或縮小信號。 Minification and magnification – resample the signal to a different resolution. ![](https://i.imgur.com/fIt7n2X.png) #### Magnification (Upsampling) 只需對重構信號進行重新採樣即可。 ![](https://i.imgur.com/jwiKO1G.png) #### Minification (Downsampling) 信號的頻率太高,無法避免混疊 兩種解決方法: 1. Increase the low pass filter width of the ideal sinc filter – more of the signal’s higher frequency content is removed; this can effectively blur the image. (增加低通濾波器的寬度,使信號中高頻成分更多部份可以被去除,使圖像模糊) 2. Blur the image first (using any method), and then sample it. (先模糊圖像 ### Anti Aliasing Strategies (抗鋸齒) Pixel needs to represent average color over its entire area(像素需要代表整個區域的平均顏色) 1. Prefiltering (預過濾) 2. Supersampling (超採樣) ![](https://i.imgur.com/hmoGUqN.png) ![](https://i.imgur.com/cbvIQzf.png) ![](https://i.imgur.com/aymXzra.png) ### Adaptive supersampling: trace at higher resolution only where necessary. ### FSAA (Full Screen Anti-Aliasing) Nvidia GeForce 2: use ordered grid supersampling (OGSS). 3dfx voodo 5: rotated grid supersampling (RGSS) ![](https://i.imgur.com/awDNwMx.png) ### Analytic Area Sampling • Eliminates edge aliases. • Clip polygon to pixel boundary. • Sort fragments by depth. • Clip fragments against each other. • Scale color by visible area. 按可見區域縮放顏色 • Sum scaled colors.對縮放的顏色求和 ![](https://i.imgur.com/8js72vb.png) ### A-Buffer 將像素細分為4x4位掩碼。 裁剪=對位掩碼的邏輯操作。 位掩碼用作查找表的索引。 ![](https://i.imgur.com/2a4xtnp.png) ### Multisampling AA 1. 計算每個網格單元的多邊形的近似覆蓋率。 2. 通常為網格單元每個表面計算一次照明值,並由所有表面樣本共享。 ### Multisampling AA (cont) •子像素無多重紋理獲取– 對子像素使用相同的紋理顏色。 •旨在提高性能 •僅在邊緣像素處執行 ### Quincunx Multisampling •每個角樣本值分配到其四個相鄰像素。 •中心樣本的權重為1/2,每個角樣本的權重為1/8。 •角點樣本影響四個像素,強度是中心樣本僅影響一個像素的四分之一。 ![](https://i.imgur.com/zHSUw6C.png) Generate 2 samples per pixel Can produce quality comparable to 4x with half of the cost ### Stochastic Sampling •眼睛對圖案極為敏感。 •從採樣中刪除圖案。 •將樣本隨機分佈在整個像素上,每個像素具有不同的採樣模式。 •隨機化趨向於用噪聲代替重複的混疊效果,人類視覺系統對此更為寬容。 •最常見的隨機採樣是抖動。 ### ATI - SMOOTHVISION •使用抖動的採樣模式。 •每個像素都有備用的預編程抖動採樣位置。 •偽隨機外觀。 •使用每組16個採樣點。 •劃分為不同數量的像素。 •同一組內的像素使用不同的採樣位置集組合 ![](https://i.imgur.com/W7s4jYM.png) ## Anti-Aliased Texture Mapping 上面的抗鋸齒方法可以更好地消除鋸齒邊緣,但不能消除紋理鋸齒。 ### Magnification Common methods: nearest neighbor (box filter) or linear interpolation (tent filter). ![](https://i.imgur.com/etSPSFY.png) ### Bilinear Interpolation 對四個相鄰紋理像素的紋理值進行線性插值。 ![](https://i.imgur.com/uGJ1jIH.png) ### Minification Several texels cover one pixel (==undersampling happens==). Potential for aliasing since texture signal bandwidth greater than frame buffer. Solution: Either ==increase sampling rate== or ==reduce the texture frequency==. We will discuss: 1.Mip-mapping 2.Rip-mapping 3.Sum area table(SAT) #### Mip-Mapping •原始紋理使用一組低分辨率紋理進行了增強。 •使用哪種分辨率取決於屏幕投影尺寸– 嘗試將像素與紋素的比率維持在接近1的水平。 •(考古)在貼合不同分辨率時,解決多texel配1 pixel的情況,用多組不同解析度的texture盡量去達到1 texel配1 pixel ![](https://i.imgur.com/f9QVKNu.png) 創建紋理的分辨率金字塔 – 以一半的分辨率重複對樣本進行採樣。 – 直到長跟寬變成==1*1==。 – 需要額外的存儲空間。 – 使用最接近屏幕分辨率的紋理。 – 或在兩個最接近的分辨率之間進行插值。 ![](https://i.imgur.com/D7jgaFh.png) ##### Mip-Mapping Problem 只==適用正方形==,矩形可能無法檢索,實際上可能需要個別對長或寬進行縮放 <br> Over-blurring : 一個pixel上佔的==u,v方向的texel比例差太多==(ex:u方向的texel有10個,v方向的texel只有1個) ![](https://i.imgur.com/XLpTGam.png) #### Rip-Mapping (Hewlett-Packard’s term) 糾正mip-mapping,分離X和Y的過濾器 可以組合出==不同的長跟寬== ![](https://i.imgur.com/GbXOw0h.png) ==Four times the amount of storage== is required. With a 16x16 base texture map, the associated mip-map set contain 8x8, 4x4, 2x2 and 1x1; the rip-map resolutions would be 16x8, 16x4, 16x2, 16x1, 8x16, 8x8, 8x4, 8x2, 8x1, 4x16, 4x8,4x4, 4x2, 4x1, 2x16, 2x8, 2x4, 2x2, 2x1, 1x16, 1x8, 1x4, 1x2 and 1x1. #### Summed Area Table (SAT) •(考古) ![](https://i.imgur.com/n90FubL.png) SAT每個點都是左下區域的總和 ```python= # python code SAT[10,15] = SUM(SAT[0:11,0:16]) # 舉例 ``` ==計算紋理中像素區域的矩形邊界框,然後使用求和面積表計算平均顏色(即在進行放大時過濾紋理像素)。 R = SAT[B] – SAT[C] – SAT[D] + SAT[A]== <br> The average value can be computed by: R / num of texels in R 如果區域R不只是一個texel(ex:16個texels) -> R/num(這裡的num=16) ==Less blurry than Mipmapping.== <br> 沿對角線方向觀察紋理時仍模糊不清,是因為 ==理想邊界的pixel數量大於實際畫出來的piexl數量== (ex:在邊界的地方,理想上應該要有5個pixels,但螢幕上只能畫一個pixel)。 ![](https://i.imgur.com/JN2Gxut.png) ### Accumulation Buffer •增加OpenGL的分辨率。 •渲染場景16次。 •剪切投影矩陣。 •樣品在像素中的不同位置。 •平均結果。 •抖動,但每個像素中的抖動採樣模式相同。