이 시리즈는 3차원 그래픽스에 대해 공부한 내용들을 담고 있습니다.
참고 자료 :게임 프로그래밍을 위한 3차원 그래픽스 (한정현, 홍릉과학출판사)
,OpenGL ES를 이용한 3차원 그래픽스 입문 (한정현, 홍릉과학출판사)
등
조명Lighting은 물체와 빛 사이의 상호작용을 처리하는 기술이다.
이전 포스트의 렌더링 파이프라인을 참고해보자.
Pixel-Shader Stage에서는 본 포스트에서 다룰 조명과 함께 텍스처링 정보 등을 복합적으로 고려하여 실제로 출력될 픽셀의 색상을 결정한다.
빛의 근원인 광원Light Source는 다음과 같은 여러 형태로 나타난다.
Point Light
: 한 점으로부터의 모든 방향에 대한 광원.
Directional Light
: scene의 매우 먼 지점으로부터 오는 강력한 광원.
거리가 매우 멀기 때문에 광선이 평행하다고 취급하며 scene의 모든 지점에 대해 동일한 영향을 미친다. (ex. 햇빛)
Spotlight
: 원뿔Cone 형태의 광원.
광원의 중심점과 원뿔 밑면의 중심으로 갈수록 빛이 세진다.
Phong model은 다음의 네 가지 term으로 이루어진다.
각 term에 대한 더욱 자세한 설명은 별도로 기술한다.
Diffuse
: 표면에 대한 난반사
Specular
: 표면에 대한 정반사
Ambient
: 공간 내의 다른 물체들에 의해 반사된 빛
Emissive
: 물체의 빛 흡수에 대한 term
diffuse와 specular는 광원으로부터 물체 표면에 들어오는 빛인 직접 조명을 다루고, ambient는 다른 물체로부터 반사된 간접 조명을 다룬다.
반면 emissive는 물체가 스스로 빛을 발산하는 발산광에 대해 다룬다.
lambert's law에 따라 정의되는 term이다.
Lambertian Surface
: 관찰자가 바라보는 각도에 관계없이 같은 밝기로 보이는 표면
빛이 lambertian surface(diffuse surface)에 부딪히면 모든 방향에 대해 빛이 반사(난반사)되며, 광원의 세기가 diffuse에 가장 큰 영향을 미친다.
Lambertian surface의 특성에 따라 관찰자의 시선은 관찰자에게 들어오는 빛과 무관하다.
light direction l 과 surface normal n 사이의 각도(입사각)가 작을수록 더욱 많은 빛을 받고, 이로 인한 빛의 세기는 다음 수식으로 구할 수 있다.
이 때 빛을 받기 위해서는 가 90도 이하의 값을 가져야 하므로 는 양수이다.
따라서 max()을 사용하여 빛의 세기가 항상 0 이상의 값을 가지도록 하였다.
이를 통해 가 0일 때(광원이 수직으로 있을때) 들어오는 빛의 양이 가장 많음을 알 수 있다.
또한, 인 경우에는 빛을 받지 못함을 알 수 있다.
반사되는 빛의 색상은 로 정의되고, 의 출력은 벡터들의 각 원소를 곱한 벡터이다.
( ex. )
와 는 각각 광원의 RGB 색상, 물체의 diffuse 계수를 나타낸다.
앞선 빛의 세기와 색상 값을 통해 최종적으로 정의되는 diffuse term은 다음과 같다.
diffuse =
물체 표면의 하이라이트를 만드는 데 사용되는 term이다.
view vector(시선 벡터) v 와 reflection vector(반사 벡터) r 을 통해 정의된다.
view vector v 는 물체 표면의 점 p로부터 카메라를 향하는 벡터로 정의되고(카메라 시선과 반대 방향), reflection vector r 이 물체 표면과 이루는 반사각은 normal n 과 light l 의 입사각과 같으므로 다음과 같이 정의되는 식을 얻을 수 있다.
증명은 간단하니 아래 그림을 참고하자.
반사 벡터 r과 시선 벡터 v 사이의 각도를 라 할 때, 의 값이 작아질수록 카메라가 받는 빛의 양이 많아질 것이다.
sh를 표면의 매끈함을 나타내는 term이라고 할 때, 정반사가 일어나는 원뿔 속에서 하이라이트가 감소되는 정도는 다음과 같이 근사적으로 계산된다.
r = v 일 경우 는 sh에 상관없이 1의 값을 가지고, 하이라이트는 최대로 표현될 것이다.
sh term은 의 n제곱으로 결정되는데, n이 커질수록 급격히 sh 값이 변할 것이다.
즉, 표면이 매끄러울수록 sh는 커질 것이고 sh가 클수록 하이라이트가 작게 표현될 것이다.
specular 항은 다음과 같이 정의되며, diffuse와 마찬가지로 는 광원의 색상, 는 물체의 specular 계수이다.
는 주로 gray-scale로 표현되어 물체 표면의 하이라이트가 광원의 색을 반영하게 한다.
specular =
공간 내의 다양한 물체로부터 반사된 빛, 간접 조명을 의미한다.
공간 내의 모든 방향으로부터 들어온 빛에 영향을 받으므로, 빛을 받은 p점은 모든 방향에 대해 빛을 반사한다.
따라서 ambient는 p의 노멀 및 시선 벡터에 영향을 받지 않는다.
ambient는 RGB 색상 와 물체의 ambient 계수 에 영향을 받아 다음과 같이 표현된다.
노멀 및 시선 벡터에 영향을 받지 않는 것을 볼 수 있으며, 주로 상수로 설정된다.
ambient =
emissive는 물체가 자체적으로 발산하는 빛을 표현하며, 이 RGB 색상은 로 표현된다.
phong model의 한계로, ambient는 광원으로 취급되지 않아 다른 물체의 조명에 기여하지 못한다.
emissive =
최종적으로 phong model은 앞선 네 개의 term의 합으로 표현된다.
emssive는 물체가 자체적으로 내는 빛이므로, 빛을 내지 않는 물체에 대해서는 이다.
phong lighting을 위해서 pixel shader는 각 vertex에 대해 lighting을 수행한다.
pixel shader 내에서 각 계산은 독립적으로 수행되며, 서로의 데이터를 공유할 수 없다.
따라서 계산에 사용되는 Constant buffer를 갱신하여 데이터에 일괄적으로 영향을 준다.
각 vertex에 대해 빛 벡터 l, 반사 벡터 r, 노멀 n, 시선 벡터 v가 필요하다.
이 때, 광원 l을 ambient로 가정하자.
ambient는 모든 vertex에 대해 동일한 방향을 가지기 때문에 l은 constant buffer를 통해 pixel shader에 제공된다.
반대로 n,r,v는 vertex마다 다르게 표현되며, r은 n과 l로 표현될 수 있다.
따라서 최종적으로 pixel shader에는 각 vertex별 n과 v를 제공해야 한다.
빛 벡터 l이 world space에서 정의되어 있으므로 diffuse를 구하는 과정에서 l과 결합될 n 역시도 world space vector여야 한다.
따라서 vertex shader는 object space에서 정의된 각 vertex normal을 world transform하여 world space normal로 변환하여 이를 래스터라이저에 전달한다.
래스터화 단계에서는 이를 보간하여 각 픽셀(프래그먼트)마다 world space normal을 할당한다.
View vector는 world space에서 정의되어야 한다.
vertex shader는 각 vertex의 object space position을 world transform하여 world space position으로 변환한다.
이렇게 변환된 world space 상의 position은 EYE와 연결되어 view vector를 정의한다.
normal을 구하는 과정에서와 마찬가지로 래스터라이저는 구한 view vector를 보간하여 픽셀 별 world space view vector를 할당한다.
앞서 래스터라이저로부터 각 픽셀(프래그먼트) 별로 보간된 normal과 view vector를 제공받았다.
l은 constant buffer로부터 제공받고, r은 l로부터 계산함으로써 필요한 world space vector를 모두 준비했다. ()
이제 각 vertex에 대해 phong lighting을 수행할 수 있다.