센로그
8. Lighting 본문
◆ Phong Lighting Model
Raterizer에서, face 안쪽의 pixel 데이터를 생성해줬었다. 이제, 이 pixel들에 하나하나 접근할 수 있다!
Pixel Shader에서는 p1~pn까지 가득 채워져있는 pixel data들에 각각 접근해서 pixel의 색깔을 결정함
이 pixel 정보들을 일렬로 세우고, 병렬 처리로 한번에 계산해서 pixel마다의 색깔을 결정하는 것. (병렬이므로, 인접한 애들에 대한 접근 까지는 못함)
이때 pixel의 색깔을 결정하는 중요한 두 가지 요소가 있다.
- Texturing (벽지 바르기)
- Lighting (빛 처리)
이번에는 그중 Lighting에 대해 다뤄볼 것이다.
Lighting이란, object와 light 간의 상호작용을 다루는 기술을 의미한다. Shading이라고도 불림.
Lighting 방법 중 유명한 방법인 Phong Model에 대해 알아볼 것임.
처음에 배우기 젤 간단함! 최근에는 좀 더 발전된 형태인 PBR(Physically Base Rendering)이 더 많이 쓰이긴 함 ㅇㅇ
■ Phong model은 다음 네가지 요소로 구성되어 있다.
- Diffuse
- Specular
- Ambient
- Emissive
◆ Light Sources
Light Source에도 종류가 있다. 종류에 따라 어떻게 빛을 비추는지가 달라짐.
다음 종류들을 보자.
- Point Light
- Directional Light
- Spotlight
- Ambient
◆ Light Sources - Point Light
하나의 포인트로부터 전방향으로 빛을 뿜어내는 것
거리에 따라 세기 바뀜
포인트로부터의 거리에 따라 라이트 세기가 바뀜
◆ Light Sources - Directional Light
어느 곳에 있든지 한 방향으로 빛을 비춤. (각도 바뀌면 방향 달라짐)
거리가 멀든 말든 세기는 상관 없음.
엄청먼 거리에서 온 태양빛은 거의 직선으로 표현되는 ㅇㅇ
거리가 바뀌든 말든 세기는 상관없지만, 방향은 영향을 줌
◆ Light Sources - Spotlight
거리와 방향에 영향을 받는 콘(cone) 모양의 빛.
가로등이나 형광등 느낌.
◆ Light Sources - Ambient
주변광.
간접광들을 모두 다 계산하기보다는, 차라리 상수 C만큼의 세기로 은은하게 밝혀주도록 하자~
Light Source가 없더라도, 기본적으로 밝혀주도록 하는 빛.
세기는 완전히 일정함. (상수)
◆ Phong Model
빛이 어떤 메쉬에 도달했을 때 어떻게 내 눈에 들어올지 정확히 계산은 못하지만, 몇 가지 작용이 섞여있을거야.
Phong model은 기본적으로 적당히 그럴듯해보이게 lighting을 근사하는 모델임.
Phong Model은 어떤 작용들을 모델링하냐면!
- Diffuse : 흩어지는 빛. 난반사
- Specular : 반사 광택. 정반사
- Ambient : 주변광
- Emissive : 자체발광
◆ Diffuse Term
Diffuse light는 light가 물체의 표면에 닿을 때 주변으로 흩어지는 것을 표현함
표면에서 난반사가 일어남.
이때 난반사는 빛의 세기와 상관 없음.
그리고 카메라의 위치와도 상관 없음.
light 방향과 표면의 법선 방향과 관련있음~
◆ Diffuse Computation. 난반사 계산
nㆍl 고려
light vector l과, surface normal n에 대해 고려해보자.
l과 n의 각도가 0일때 가장 쎔. (cos0 = 1)
Diffuse term은 다음과 같이 정의된다.
s_d는 빛의 RGB 색상.
m_d는, 오브젝트의 material의 색깔이 light의 색깔에 영향을 주도록 하기위한 값.
흰색 빛 (1, 1, 1)이 있다고 가정해 봅시다.
만약 물체가 노란색으로 보인다면, 이는 물체가 R과 G를 반사(reflect)하고 B를 흡수(absorb)한다는 의미입니다.
우리는 이러한 종류의 필터링을 material parameter를 통해 쉽게 구현할 수 있습니다.
예를 들어, (1, 1, 0)이라면 (1, 1, 1)⊗(1, 1, 0)=(1, 1, 0)이 됩니다.
◆ Specular Term
rㆍv 고려.
r은 n과 l 사용해서 만듦
금속에 빛이 들어와서 튕겨나오는 걸 모델링한 것.
light vector l 외에, view vector v와, reflection vector r이 추가로 필요하다!
view vector v : 반사각에서 바로 바라보느냐 아니냐? 에 따라서 달라지기 때문에 필요함.
내 눈에 반사되어 들어올 때 얼마나 반짝이냐에 관한 것.
Reflection vector r: reflection vector에 가까울수록 밝고, 일정거리 넘어가면 안보이도록 함.
▽ Reflection vector 계산하는 법~
n과 l이 단위벡터라고 할 때~ 이렇게 계산.
표면의 반짝거림은 sh를 사용해 표현할 수 있음. (shiness)
ρ 가 반사벡터 r과 view 벡터 v 사이의 각도를 의미한다고 하자.
- 표면이 완전히 반짝거리는 경우(sh값이 엄청 큼), 어떤 점 p에서의 highlight는 ρ = 0일 때만 보임. (== 카메라가 바로 위에 있다)
즉, 조금만 고개를 돌려도 눈 안부시게 됨. - 표면이 완전히 반짝거리지는 않는 경우(sh값이 적당), 최대 하이라이트는 ρ가 0일 때 발생하지만, ρ가 증가함에 따라 약해짐.
sh 값이 커지면, cos에 붙는 승수가 커지는 셈이다.
cos에 승수가 붙으면, 아래와 같이 애가 가로로 엄청 찌그러짐.
- sh가 증가하면 각도(ρ)에 따라 highlight가 더 급격하게 감소함.
- reflection vector r과 view vector v사이의 각 ρ가 0에 가까울수록, 내눈에 더 세게 보임.
실제 구현에서 specular term은 다음과 같이 계산됨
m_d때와는 다르게, m_s는 RGB color보다는 gray-scale(회색조) value를 사용함.
m_s는 표면의 highlight를 light source의 색상으로 표현할 수 있도록 해줌.
◆ Ambient Term
간접광을 고려해, 전체적인 조명을 주는 것
주변광은, 간접광에 연관된 일반적인 빛을 표현한다. 씬에 존재하는 수많은 object들에 반사된 빛을 표현함.
다양한 물체들에 튕겨서 한 표면으로 도달하고, 그 포인트 표면에서도 모든 방향으로 동일한 강도로 튕길 것임.
그러므로 상수로 표현해서 그럴듯하게 함. 모든 pixel들에 일정한 양의 조명을 주는 것.
간접광을 고려함으로써 좀더 현실적인 빛을 표현할 수 있음.
◆ Emissive Term
표면에서 자체발광
표면 자체로부터 방출(emit)되는 빛.
◆ Phong Lighting Model
Phong Model은, 앞에서 배운 네가지 요소( Diffuse, Specular, Ambient, Emissive)들을 다 합쳐서 최종 결과를 출력함!
아래 식의 term 하나하나가 각각 diffuse, specular, ambient, emissive 의미. 다 더한거 ㅇㅇ
◆ Per-pixel Lighting
이제 계산한 빛을 실제로 어떻게 구현하는지 보자.
< Per-vertex lighting vs Per-pixel lighting >
좌측의 vertex별 라이팅은 정말.. 말 그대로 vertex별로 라이팅한 것처럼 보임 ㅇㅇ 부자연스러움
vertex 단위로 빛을 결정하고, 내부 픽셀들에서 interpolate하는 것.
요새는 잘 안씀. 다 per-pixel lighting으로 함.(pixel 단위로 빛을 결정)
■ per-pixel lighting
Object의 표면 위에, 개별적인 픽셀로 구성된 두 지점이 있다고 하자.
(계산상 편의를 위해, 모든 표면에 대해 방향이 동일한 direction light l를 정의한다.)
Pixel shader는 l, n, r, v를 사용해서 lighting을 계산한다.
l은 보통 constant buffer을 통해 pixel shader에 제공된다.(global light vector)
반면 n, r, v는 object의 표면에 따라 달라진다.
r = 2n(nㆍl) - l로 계산하고, n과 v는 pixel shader가 연산을 수행할 때마다 달라진다!
그런데!
l이 world space vector이기 때문에, n도 world space에서 정의되어야 한다. (coordinate 통일)
이를 위해 vertex shader가 각각 vertex의 object space에서의 normal을 world space normal로 변환(L^-T)하고,
이 값을 Rasterization stage에 넘겨준다. 그 뒤의 변환이 일어나기 전 world space에서의 normal 값을 넘겨준다는 뜻
Rasterization stage에서, 각각의 pixel들에 대한 normal n을 제공하기 위해 vertex normal들이 보간된다.
vertex normal인 n_1과 n_2를 보간해서 pixel normal n_a와 n_b를 각각 만들어줌!
또 world space에서의 정의가 필요한 벡터가 남아있는데, 바로 view vector v가 필요함.
픽셀 a와 b에 대해, 각각 v_a와 v_b가 필요함.
이를 위해 vertex shader는 각 vertex의 object space position을 world space position으로 변환하고,
world space에서 정의된 카메라 위치 EYE와 연결함. vertex별 view vector을 만들어서 넘겨준다는 뜻.
그리고 Rasterization으로 넘겨서, vertex별 view vector을 보간해서 pixel별 view vector을 구함.
자! 이제 우리한테는 pixel shader의 input으로 들어오는 n, v가 있고
constant buffer로 주어진 l이 있다. (아까 계산상 편의를 위해 정의한다고 했었음)
그럼 우선 reflection vector r을 구함. (r = 2n(nㆍl)-l)
그럼 world space에서의 l, n, r, v 다 구했다!!!
따라서 얘네들을 가지고 diffuse, specular, ambient, emissive 구해서 phong model을 구현할 수 있다~
※ l, n, r, v는 world space에서 정의된다는 사실 잊지않기~
◆ Blinn-Phong Reflection Model
Phong Model에서 ρ가 90도 넘을 때 Specular가 바로 급격하게 감소하는 문제를 개선한 모델
h가 l+v를 반으로 나눈 단위벡터라 할 때, 기존 rㆍv 대신에 nㆍh를 고려하는 방법.
Phong Model에서 ρ가 90도 넘으면 Specular가 급격하게 감소해서, 어떤 조건에서는 사실적이지 않게 보임.
여기서 내적이 cos 연산을 포함하기 때문임 ㅇㅇ
90도를 넘으면, cos값이 음수가 되기 때문에 max()에서 0을 택하게 되는 것이 문제였음.
급격하게 바뀌는 부분에 대해서 경계(cut-off)를 만들기 때문에 부자연스러워 보임.
이 문제를 해결하기 위해서, Blinn-Phong에서는 기존 Phong과는 다른 방식으로 specular term에 접근한다.
reflection vector r 대신에, halfway vector h의 개념을 도입해 reflection을 구현한다.
h는 light vector l과 view vector v에만 관련이 있는데, l+v를 정확히 반으로 나눈(bisects) 단위 벡터를 의미한다.
h를 사용해 specular term을 다음과 같이 계산한다.
일반 Phong model에 비해, 90도 넘어가면 급격하게 빛이 사라져서 경계가 형성되던 현상이 완화됨.
이 개념을 나중에 PBR에서도 사용하기 때문에, 알아두자!
'게임 > 그래픽 프로그래밍' 카테고리의 다른 글
10. Euler transforms and quaternions (0) | 2023.05.28 |
---|---|
9. Output-Merging (0) | 2023.05.28 |
7. Image Texturing (0) | 2023.05.26 |
6. Rasterization (0) | 2023.05.13 |
5. Input Assembler & Vertex Processing(2) (0) | 2023.05.12 |