OpenGL의 기본 조명 공식
OpenGL의 기본 조명 공식은 다음과 같다.
위의 공식에서 첫 번째 줄의 경우, 첫 번째 "ecm"항 은 물질 스스로 발하는 빛, 즉 emission 값을 의미하고 두 번째 항 "acm * acs"은 공간의 전체적인 앰비언트 반사를 통한 빛의 값을 의미한다. 그리고 두 번째 줄에서, vertex가 가진 여러 속성들로 퐁의 조명 모델에 기반한 계산을 하여 실질적으로 칠해질 색깔을 결정하는 역할을 한다.
우선, 시그마는 0번부터 n-1번까지의 각 조명을 의미한다. 즉, 공간에 조명이 n개가 있으면 각 조명에 의해 물체로부터 반사되는 색의 정도를 계산해서 다 합해주는 것이다. 기본적으로 퐁의 조명 모델에서는 앰비언트 반사, 난반사, 정반사라는 세가지 형태의 반사를 고려한다.
일반항에서 일단 앞의 atti와 spoti는 빼놓고 뒷부분을 먼저 살펴보면, 세 항은 각각 앰비언트 반사(ambient), 난반사(diffuse), 정반사(specular)를 의미한다. (참고로, 굵은 글씨의 a, d, s는 각각 ambient, diffuse, specular를 의미하고, 만일 밑에 cm이라 쓰여있으면 이는 물체의 해당 반사에 대한 반사 계수(material parameter)를, cli라 쓰여있으면 이는 i번 조명의 광원의 색깔 값(light)을 의미한다. 예를 들어, acm은 앰비언트 반사 계수를, scli는 광원 i의 정반사 색깔을 의미한다.)
첫 번째 항은 세 형태의 반사 중 앰비언트 반사를 의미한다. 반사되는 빛의 색깔은 앰비언트 반사 계수 acm과 앰비언트 광원의 색깔 acli를 각 R, G, B 채널끼리 곱하며 구하므로, 최종적으로 acm * acli 가 된다.
두 번째 항은 난반사를 의미한다. 우선 n은 계산하고 있는 꼭짓점에서 물체에 수직인 법선 벡터를 의미한다. 그리고 V는 꼭짓점의 위치를, Ppli는 광원의 위치나 방향(점 광원이면 위치(w속성의 값이 0이 아님)고, 평행광원이면 방향(w속성의 값이 0)일 것임)을 뜻하므로, 벡터 VPpli 는 광원에서 꼭짓점으로 들어오는 것의 반대 방향에 대한 단위 벡터(즉, 광원 벡터)이다. 램버트의 코사인 법칙에 의하면 반사되는 빛 에너지의 양은 두 벡터(법선 벡터와 광원 벡터) 사이의 각을 θ라 할 때 cosθ에 비례한다. 따라서 n과 벡터 VPpli 를 ⊙연산 하여 반사되는 빛의 양을 구하고, 이를 난반사 계수 dcm과 난반사 광원의 색깔 dcli의 각 RGB 채널끼리 곱한 것에 곱해준게 위의 항이 되며, 이로써 난반사로 반사되는 빛의 색깔을 구할 수 있다. (참고로, ⊙연산은 max(두 벡터의 내적, 0)을 의미한다. 즉, 내적 결과가 양수가 아니면 0을 곱하여 최종 RGB값이 0이 되도록 하는데, 이는 OpenGL에서는 뒤에서 들어오는 빛을 고려하지 않음을 의미한다).
마지막 항은 정반사를 의미한다. hi는 해프웨이 벡터를 의미하는데, 해프웨이 벡터란 광원 벡터와 관찰자 벡터(눈의 위치)의 가운데 방향으로의 단위 벡터를 의미한다. OpenGL에서 해프웨이 벡터는 만일 지역 관찰자를 사용한다면 관찰자가 눈 좌표계에서 (0,0,0)의 좌표에 위치하였으므로(w는 점이므로 0이 아님) 꼭짓점에서 눈(원점)으로의 방향인 벡터 VPe를 써서 벡터 VPpli + 벡터 VPe 가 되고, 무한 관찰자를 사용한다면 z축방향을 관찰자 방향으로 사용하므로 (0, 0, 1)방향을 써서(w는 방향이므로 0임) 벡터 VPpli + (0 0 1 0)^t가 된다. 이렇게 구한 해프웨이 벡터의 단위 벡터를 난반사와 마찬가지로 법선 벡터와 ⊙연산하고, 여기에 정반사는 특정방향을 중심으로 집중 반사하는 것을 뜻하므로 정반사 지수(Srm)만큼 제곱해주어 반사되는 빛의 양을 구한다. 이후 이 값을 정반사 계수 scm과 정반사 광원의 색깔 scli를 각 RGB 채널끼리 곱한 것에 곱해준다. 그리고 마지막으로 fi라는 0또는 1의 값을 가지는 추가 변수를 곱해준다. fi에 의해 정반사 값이 유효하거나 유효하지 않아질 수 있는 건데, 이 변수는 n⊙VPpli 값이 0이면 0, 그렇지 않으면 1 값이 된다. 즉, 정반사도 난반사와 마찬가지로 법선 벡터와 광원 벡터의 내적 결과가 양수가 아니면(빛이 뒤에서 들어오면) 최종 RGB값을 0으로 만들어버리고, 그렇지 않은 경우에만 1을 곱하여 반사되는 RGB 값을 살린다는 의미이다.
이렇게 구한 앰비언트 반사, 난반사, 정반사로 인한 반사 색깔을 모두 더한 후에는 추가로 빛의 감쇠 효과를 나타내는 atti와 스폿 광원임을 나타내는 spoti, 두 값이 더 곱해진다.
우선 OpenGL에서 atti의 값은 만일 광원이 평행 광원이면(Ppli에서 w값이 0) 빛이 무한히 멀리 있으므로 감쇠 효과가 없으므로 1이 된다. 반면 점 광원이면(Ppli에서 w값이 0이 아님) 광원부터 꼭짓점까지의 거리에 따라 완만하게 반사되는 빛의 값이 작아지게 하기 위하여 atti값이 위와 같이 된다(인자인 k는 OpenGL에서 직접 설정할 수 있다).
spoti값은 만일 절단 각도인 Crli가 180도라면, 즉 평평하게 쭉 펼쳐져 있어 일반적인 점광원의 동작을 의미한다면 1.0이 되어 특별한 효과를 내진 않는다. 반면, 만일 꼭짓점이 절단 각도의 범위 밖에 있으면(= PpliV ⊙ Sdli < cos(Crli), 여기서 Sdli는 빛의 중심 방향을 의미한다. 빛에서 꼭짓점으로의 방향과 빛의 중심 방향 사이의 각도의 cos값이 절단 각도의 cos값보다 작다는 것은, 사이 각도가 절단 각도보다 더 크다는 것이므로 벗어났음을 의미한다) 빛이 들어오지 않는다는 의미이므로 0이 되어 조명 효과를 아예 끈다. 마지막으로 절단 각도의 범위 내에 있으면(= PpliV ⊙ Sdli >= cos(Crli) , cos값이 더 크므로 사이 각도가 더 작음. 조명 범위 내에 있음) 빛이 들어오되 조명의 외곽으로 갈수록 어두워지도록 (즉 cos^Srli값에 해당)이 위 값이 spoti가 된다(즉 cos^Srli값에 해당).
이렇게 하여 위 공식이 조명i에 대한 최종 반사 색깔이 된다. 결론적으로, 물질 스스로 발하는 빛인 ecm과 공간의 전체적인 앰비언트 반사인 "acm * acs", 그리고 모든 조명으로부터의 반사색깔을 더하면
가 된다. 이것이 바로 OpenGL의 기본 조명공식이다.