---
# System prepended metadata

title: 2020計算攝影學整理筆記(上)
tags: [CCU, ' 計算攝影學']

---

---
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次。 

•剪切投影矩陣。 

•樣品在像素中的不同位置。 

•平均結果。 

•抖動，但每個像素中的抖動採樣模式相同。

