Rasterization(9) - 블린-퐁 쉐이딩
버텍스 쉐이더에서 버텍스 색을 결정하는 방법이 있고,
픽셀 쉐이더에서 계산하는 방법이 있습니다.
그렇지만 픽셀을 하나하나 계산하는 것보다
버텍스 쉐이더에서 색을 결정하는 것이 빠릅니다.
대신 렌더링 품질이 떨어집니다.
그래서 요즘에는 GPU가 워낙에 빠르기 때문에
픽셀 쉐이더에서 색을 결정하는 일이 많아졌습니다.
퐁 쉐이딩을 기반으로 블린-퐁 쉐이딩의 원리를 알아볼 예정입니다.
기본적으로 퐁 쉐이더는 ambient, diffuse, specular로 나누어져 있습니다.
ambient는 조명과 상관없이 그 색을 픽셀 쉐이더에서 return 해주면 됩니다.
모든 픽셀의 색을 다 같은 색으로 만들면 입체감이 없어지게 됩니다.
3차원 그래픽에 ambient가 있어야 되는 이유
직접적으로 오는 조명과 고려한다면 빛을 받은 부분만 밝게 나옵니다.
빛을 받지않은 부분들은 아주 어둡게 나옵니다.
전역 조명은 직접적으로 오는 조명뿐아니라 전역 조명까지 고려합니다.
전역 조명은 빛이 직접적으로 와서 닿는 것 뿐만 아니라
다른 물체에 반사되는 것 까지 고려하는 것을 말합니다.
Local illumination(직접광) -> LI
빛이 오는 것만 처리하는 개념
Global illumination(간접광) -> GI
빛이 오고 반사되어 간접적으로 조명처리를 하는 개념
Ray Tracing 개념에서도 말씀드렸다시피 광추적은 굉장히 느립니다.
Rasterization을 사용하는 Real-Time Grapichs는 속도가 중요하다보니
일단 LI로 구현합니다. 그런다음 GI로 사실성을 높혀가는 방법을 사용합니다.
속도도 높혀가면서 품질도 높이는 기법으로 사용하게 됩니다.
그래서 완전 어두운부분을 어둡게 두지 않고 ambient color로 덧붙혀주는 것입니다.
간접광을 아주 단순하게 처리할 때 ambient로 처리하게 됩니다.
그래서 간접광이 많은(렌더링 품질이 높은) 곳에서는 ambient를 쓰지 않습니다.
(물체가 그려졌는 지에 대한 용도로 많이 사용됨)
Diffuse와 Specular는 입체광을 표현할 때 사용합니다.
우리가 물체를 본다고 생각해봅시다.
태양같은 광원이 있어야 물체 표면이 반사되 색의 일부를 눈으로 볼 수 있습니다.
그래서 조명이 색이나 세기가 우리가 보는 색과 연관이 있게 됩니다.
우리가 보는 색은 조명에서부터 시작한다고 보시면 됩니다.
diffuse가 조명하고 관련있늗데 (light.r * mat.r, light.g * mat.g, lgiht.b * mat.b)
이런 식으로 빛과 물체의 표면색을 결정하여 사용할 수 있습니다.
빛의 종류
지구와 태양은 아주 멀기 때문에 그래픽스에서 광선들은 서로 평행하다고
가정합니다. 그래픽스에서의 광원은 대표적으로 3가지로 분류합니다.
Directinal Light, Point Light, Spotlight
빛의 RGB성능이 강한 strength와 빛의 방향을 가지고 있는 Directional Light,
한 점에서 빛이 퍼져나가는 Point Light,
특정 부분에 빛이 집중되는 Spotlight가 있습니다.
기본적으로 그래픽 작업시 Directinal Light을 가지고 처음에 만들기 때문에
그것을 기준으로 합니다.
Directinal Light의 Direction vec3(0.f, -1.f, 0.f)은 위에서 아래로 내려오는 것입니다.
Direction vec3(-0.5f, -1.f, 0.f)은 위에서 대각선 왼쪽 아래로 내려오는 것입니다.
Direction vec3(0.5f, -1.f, 0.f)은 위에서 대각선 오른쪽 아래로 내려오는 것입니다.
Lambertian Surface
Directinal Light가 위에서 빛이 쏟아지고 있다고 가정하면 쏟아지는 방향에 대해서
부딪히는 물체의 면이 수평에 가까울수록 위에서 내려오는 빛을 더 많이 받을 수
있습니다. 물체가 수직에 가까워질수록 빛을 덜 받게 됩니다.
(표면의 기울기)
이 성질을 Lambertian Surface 라고 부릅니다.
어떤 표면이 아주 울퉁불통하다고 가정하겠습니다.
그러면 빛이 표면에 부딪혔을 때 반사가 깔끔하게 되지 않고 빛이 퍼지게 됩니다.
즉, 난반사가 일어나게 됩니다. 모든 방향으로 균일하게 반사가 되는 것입니다.
광원이 물체를 뚫고 바닥쪽으로 가진 않기 때문에 반원의 형태로 반사를 유지합니다.
우리가 눈으로 물체를 바라볼 때 얼마나 밝을 지 결정하는 것은
입사해서 들어오는 빛의 방향과 표면의 기울기를 바탕으로 결정됩니다.
빛이 수평이면 많이 빛을 받아들이고 많이 반사합니다.
표면이 기울어지면 반사하는 양이 줄어듭니다.
거의 수평이라면 빛을 거의 못 받게 됩니다.
(빛이 들어오는 각도)
이 관계를 수식으로 표현한 게 위의 그림입니다.
이 때 기준으로 삼는건 어떤 면이 어떤 방향을 향하는 지(법선벡터)
수직 방향 벡터를 정합니다.
어떤 면이 빛을 많이 받을 수 있는 지 없는 지 결정할 때
표면에 수직인 법선 벡터를 계산해서 사용하는 것이 일반적입니다.
cos(0˚) 이면 1이기 때문에 가장 강한 조명을 받을 수 있고,
cos(90˚) 과 가깝다면 거의 0이기 때문에 조명을 강하게 받지 못합니다.
(각도가 작을수록 조명을 많이 받음)
Specualr 와 Diffuse의 차이
물체를 볼 수 있는 건 물체 표면에서 반사된 빛을 보는 것입니다.
그래픽스에서 표면의 색을 어떻게 결정하는 지에 대해 Reflection 이라는
단어를 많이 사용하게 됩니다.
색을 구하려고 Reflection을 하게 되는 데,
이 때 빛이 어떻게 반사될 지 결정하는 것은 물체의 표면의 성질입니다.
Diffuse Reflection 같은 경우는 사진에서 표면이 울퉁불퉁한 것을 기준으로합니다.
빛이 들어왔을 때 모든 방향으로 균일하게 반사됩니다.
Normal Vector의 각도에 따라 얼마나 많이 반사할 지 결정합니다.
(램버트 코사인 법칙)
Specular 일 때는 난반사가 아니라 빛이 들어오는 방향에 대해서
거울 반사방향으로 빛을 많이 반사합니다.
(특정 방향으로 빛을 강하게 반사)
Specular reflection 일 때는 빛을 들어와서 반사할 때 특정 방향으로
강하게 반사합니다. (거울 반사 방향, 빛이 몰려있는 것이 특징)
Specular reflection가 강한 방향이면 엄청 밝은 느낌을 받을 수 있습니다.
(거울 반사 시켜서 눈을 부시게 하는 느낌과 비슷하다)
만약 반사가 약한 방향(가운데 쯤) 에 있다면 밝은 빛을 볼 수 없습니다.
빛이 얼마나 집중될 지 얼마나 매끈한 지 표현하는 것이 바로 Shiness 입니다.
Shiness 를 높혀줄수록 특정 부분에 강력하게 빛을 받을 수 있습니다.
반대로 Diffuse reflection 일 때는 모든 방향으로 균일하게
반사합니다.
Blinn-Phong Model
퐁 모델은 퐁이라는 사람이 퐁 모델을 개발한 것이다.
이것을 발전시킨 사람이 바로 블린이라는 사람이다.
퐁 모델의 불필요한 연산들을 줄여서 효율적으로 사용할 수 있게끔 만들었습니다.
기존 퐁 모델은 완전 반사방향 R를 사용해야 했었습니다.
R · V 를 사용해야 했습니다.
V = 눈 - 렌더링 하고 싶은 지점
N = 렌더링 하고 싶은 지점의 노말 벡터
L은 Directional Light면 방향을 가져다 쓰면 되고
Point Light 같은 Light라면은 조명의 방향 - 렌더링 하고 싶은 지점입니다.
여기서 Directional Light는 위에서 내려온다라고 설정했다면
내부적으로 계산할 때 부호를 뒤집어줘야 합니다.
Specular reflection 에서는 완전 반사 방향 R하고
보는 눈을 바라보는 방향 V의 각도가 작을수록
Specular reflection 이 강하다 라고 할 수 있습니다.
하지만 R를 계산하는 것이 연산량이 더 많다고 블린이라는 사람이 판단했습니다.
계산을 많이 하는 R 벡터 대신에 H벡터를 사용합니다.
H 벡터는 V 와 L의 중간에 있기 때문에 Halfway Vector 라고 부릅니다.
R을 계산하는 것보다 H를 계산하는 게 더 빠릅니다.
R를 구해서 R · V 하는 것보다 N· H을 사용하게 된 것입니다.
결국 퐁 모델만 알면 계산하는 방식만 바꿨구나! 라고
바로 알 수 있습니다.
Phong
I(specular) = k(s) I(light) ( R · V ) ^ n(shiny)
R = 2(N(N · L) - L
Blinn-Phong
I(specular) = k(s) I(light) ( H · N ) ^ n(shiny)
H = (I + V) / 2
이 공식을 이용해 구현하면 블린-퐁 쉐이딩이 완성됩니다.
이렇게 블린-퐁 쉐이더의 원리에 대해 알아보았습니다.