☁️ Rendering Piepline

☁️ Pixel Shader
= determines the color of each pixel
- Texturing
- Lighting = 빛에 따른 빛 변화
☁️ Phong Lighting Model
☁️ Light Sources
🔎 Point light
- 하나의 point로 부터 전방향으로 빛을 뿜어냄
- point로부터 거리에 따라 intensity 결정
🔎 Directional light
- ex) 태양
- scene으로부터 엄청 멀리 떨어진 곳에서 보내는 빛
- 모두 직선 빛 / scene 전체에서 one direction
- 내가 어디에 존재하든 일정한 direction과 크기를 가진다.
🔎 Spotlight
- ex) 형광등 백열등
- cone shaped light
- 거리와 각도에 따라 intensity 결정

🔎 Ambient
- 은은하게 밝혀주는 간접광
- 반사되어 떠도는 빛을 계산하기는 어렵다
- constant value C로 뭉개버리자
☁️ Diffuse Term
🔎 Diffuse light (확산광)
- Diffuse : 물체 표면에 빛이 반사되었을 때 전방향으로 uniform하게 퍼지는 것을 modeling
🔎 Diffuse Term in Phong Lighting Model
- Diffuse surface : 충분히 울퉁불퉁한 surface
- Lambert's law
- Diffuse 조명은 표면의 밝기가 빛의 입사각과 cos(θ)에 비례
- θ: 빛의 방향과 표면 법선 벡터(normal) 사이의 각도
- view direcntion과 independent
- 얼마나 나한테 빛이 세게 들어왔는지에 관심 - 입사각에 따라 결정

🔎 Diffuse computation

- l : light vector
- n : surface normal
- sd : light source의 RGB color
- md : diffuse reflectance / light color를 바꿔준다
- max(n⋅l,0) : angle of the light
- sd x md : 빛의 색과 물체의 색을 고려해 빛의 색을 조정. approximation한 것
- white light (1,1,1)이 들어온다. 물체가 노란색이면 R,G값은 반사하고 B는 흡수한다.


☁️ Specular Term
= 물체 표면에 빛이 닿을 때, 거울처럼 특정 방향으로 강하게 반사되는 조명 효과
- highlight를 통해 표면을 shiny 하게 해준다.
- 카메라의 위치가 중요하다 = highly view-dependent


- v : view vector
- r : reflection vector
- l : light vector
- sh : shininess
- ss : light source의 gray-scale value
- ms : highlight on the surface
- r벡터 구하기

- sh = shininess
p가 0일 때 최대 / sh가 커질수록 fall-off becomes steeper


☁️ Ambient Term
🔎 Ambient light
= 간접광
- 씬 내의 다양한 물체에 반사된 빛
- 표면에 도달한 주변 조명은 모든 방향에서 동일한 강도로 산란된다.

☁️ Emissive Term
표면 자체에서 방출되는 빛을 표현한다.

☁️ Phong Lighting Model
앞서 살펴본 4가지 term을 합쳐서 그럴듯하게 보이도록 한다
- Diffuse / Specular / Ambiend / Emissive

☁️ Per-pixel Lighting
= 각 픽셀 단위에서 조명을 계산하는 방식
- Per-vertex lighting에 비해 high quality. per-vertex는 단순하게 vertex의 색에 따라 보간을 한다
- Per-vertex 방식에서는 정점만 밝기 계산을 하고, 그 사이 픽셀은 선형 보간해버림.. 부드럽지 않은 표현

- l은 directional light이기 때문에 constant vector 처럼 쓰인다.
- n,r,v는 pixel에 따라 상이하다.
- r을 직접 계산해서 vertex shader에서 pixel shader로 넘기는 파라메터를 하나 줄일 수 있다. 아니면 vertex shader에서 n,v 뿐만 아니라 r도 넘겨줘야 함.

🔎 Normal for each pixel
l은 world space vector기 때문에, n 역시 world space에서 정의되어야 한다.
- Vertex shader (object space -> world space)
각 vertex의 object-space normal을 world transform 해주고 그 결과로 나온 world-space normal을 rasterization stage로 넘겨준다.
- Rasterization : 각 pixel에 n을 할당해주기 위해서 vertex normal을 선형보간한다.
ex) 아래 예시에서 a,b pixel의 normal na, nb는 raterizer가 n1,n2를 보간해서 할당해준 것

🔎 View vector for each pixel
- pixel a,b에서는 world space view vector도 필요하다. 앞서 구한 건 world space normal.
- Vertex shader (object space -> world space)
각 vertex의 object-space position을 world transform 해주고 camera position(EYE - world space)과 연결해준다.
- per-vertex world space view vector : v1, v2
- Rasterization : 각 view vector을 선형보간한다.
ex) 아래 예시에서 a,b pixel의 va, vb는 raterizer가 v1,v2를 보간해서 할당해준 것

🔎 Pixel shader determines the pixel color
- pixel shader는 n과 v를 input으로 받고, Direct3D 프로그램에서 constant buffer로 제공되는 l을 사용하여 먼저 reflection vector r을 계산한 후 Phong 모델을 구현한다.
- r=2n(n⋅l)−l
- l,n,r,v는 모두 world space에서 정의된다.
☁️ Blinn-Phong Reflection Model
= Phong model의 modified(수정된) version
- 비록 Phong은 lighting approximation에 효율적이다.
- 하지만 가끔 specular term이 unrealistic한 결과를 낸다.
🔎 Problem of specular term
- specular term

- 이때 dot product는 cos 계산이다.
angle이 90도를 넘어가는 경우 dot product의 결과가 음수가 돼서 max( )가 결과를 0으로 만들어준다. 
- 급격한 cut off의 결과 surface에 경계(boundary)가 생긴다.

🔎 Blinn-Phong reflection model
halfway vector (h) 를 이용한다

- Blinn Phong
= halfway vector( h ) : v (view vector) 와 l (light vector)을 이등분(bisects)하는 벡터


- Phong

