2026. 8. 31. 18:24ㆍGame/Computer Graphics

CG에서 조명은 빛과 물체간 상호작용을 처리하는 기술로, 일반적으로 local illumination과 global illumination 모델 두가지로 구분된다. local illumination은 광원으로부터 물체에 직접 들어오는 빛만을 고려하는데, 문제는 실세계의 모든 물체는 간접 조명을 받는다. 그러니까 예를 들어서, 광원이 안보여도 어디서 반사되서 들어온 빛이 들어올 수 있다는 것이다. 이걸 반영한게 global illumination이라고 할 수 있겠다.
근데 RTX 드립이 괜히 나온게 아닌게, global 조명 모델은 많은 연산을 필요로 한다. 광원만 때려서 계산하면 편한데, 반사되서 들어오는걸 언제 다 계산해야된단 말인가? 그리고 (일반적인 CUDA같이) GPU 구조는 지역 조명 모델에 보다 적합하다. 따라서 엔비디아는 RT코어를 따로 둬서 레이트레이싱을 돌리는 기행을 저지르곤 한다. 쨋든 얼마나 머리가 아프고 복잡한지 한번 알아보도록 하자.
퐁 조명 모델
일단 대충 렌더링을 하려고 치면, 빛과 카메라에 도달하는 빛을 표현해야 한다. 그리고 이들 사이의 관계는 BRDF(양방향 반사율 분포 함수)로 설명 가능하며, 위대하신 퐁님께서 제안하셨다. 그래서 퐁 모델이 나오게 되었는데 - 얘는 지역 조명 모델이 되시겠다. 물론 물리적인 관점에서 볼때 정확하지는 않아서 20세기 CG의 어색함을 돋보이게 한 원흉이긴 하지만, 뭐 어쨋든. 모든 조명 알고리즘의 토대가 되시니 퐁 모델의 경우 물체의 표면에서 감지되는 색상은 디퓨즈/스패큘러/앰비언트/발산에 의해서 정의된다.
- 디퓨즈 항
디퓨즈 항은 램버트의 법칙에 따라서 설명된다. 램버시안 표면 혹은 이상적인 디퓨즈 표면으로 들어온 빛은 모든 방향을 따라 같은 강도로 반사되는데, 이를 난반사라고 부르게 된다.
이때 카메라에 의해 감지되는 빛은, 물체 표면에 들어오는 빛의 양에 비례할 것이다. 그래서 노멀 벡터랑 light vector(평행조명에서는 같다고 침)에 내적을 때리면 들어오는 빛의 양을 측정 가능하다고 할 것이다. 물론 음수로 되는 경우를 감안해서, 0과 내적값 둘중에 하나 큰걸로 결정해야만 할 것이다. 쨋든 퐁 모델의 티뷰즈 항은 아래와 같이 정의된다.

- 스페큘러 항

퐁 모델의 스페큘러 항은 물체 표면에 하이라이트(대충 정반사된 빛을 보면 보이는 가장 밝은 영역_를 만드는데 사용되며, 이를 위해서는 시선 벡터와 반사 벡터가 필요하다. 해서 뭐 이러쿵 저러쿵 계산해 주면 되는데.. 완벽하게 매끄러운 표면이라면 정반사된 빛이랑 반사 벡터가 평행일 때만 카메라에 포착되겠으나 현실은 그러지 아니하다.
따라서 하이라이트를 볼 수 있는 영역은 r을 중심으로 한 원뿔 모양으로 묘사할 수 있으며, 원뿔 속에서 하이라이트가 감소되는 정도는 대충 아래와 같이 근사적으로 계산된다.

이때 sh는 표면의 반짝임을 나타나게 된다. 쨋든 sh가 증가함에 따라 원뿔 크기가 줄어들고 이에 따라서 하이라이트가 맺히는 표면 영역 역시 줄어들게 될 것이니, 퐁 모델의 스페큘러 항은 다음과 같이 정의된다.

S_s는 광원의 RGB 색상이가, m_s는 물체의 스페큘러 계수가 될 것이다. 참고로 위에서 안적었는데 식 표기가 저렇게 되는 이유가 RGB -> (0.8,0.8,0.8)과 같이 값을 집어넣기 때문이다. 상식적으로 픽셀 하나당 RGB로 표현해야 할 것 아닌가.
- 앰비언트 항
장면 내 다양한 물체로부터 반사된 빛, 다시 말해서 간접 조명을 ambient light라고 하게 된다. 앰비언트 빛은 장면의 모든 지점에서 반사된 빛이다, 다시 말해서 모든 방향을 따라서 들어오게 되며.. p점에 들어오는 앰비언트 빛의 양은 p점의 노멀에 독립적이게 된다. 따라서 앰비언트 항은 아래와 같이 간소하게 표현된다.

물론 이건 실세계 간접 조명의 거시기함을 잡아내기에는... 좀 많이 단순화 되어 있긴 하다.
해서 뭐 결론적으로 퐁 모델은 이상의 세 개 항에 발산광을 더해서 다음과 같이 정의된다.

쉐이더와 쉐이딩 언어

3차원 물체 표면의 밝기 정도를 조절하여, 원근감 내지 깊이감을 묘사 하는것을 음영 처리 혹은 쉐이딩이라고 한다. 이때 GPU에서 굴라가는 프로그램(대게 HLSL이나 GLSL로 작성된 것)을 쉐이더라고 부르게 된다. 대충 아래와 같은 구조이다.
정점 쉐이더 -> 래스터라이저 -> 프래그먼트 쉐이더 -> 출력 병합기
물론 현대에서는 조명은 보통 프래그먼트 쉐이더에서 계산된다. 정점별로 가면 좀 머리아프다.
'Game > Computer Graphics' 카테고리의 다른 글
| 프래그먼트 처리와 출력 병합 (0) | 2026.08.28 |
|---|---|
| Scan Conversion (0) | 2026.08.27 |
| Rasterization (0) | 2026.08.19 |
| [CG] Vertex-Processing(1) (0) | 2026.07.22 |
| [CG] 폴리곤 메쉬 표현 기법 (0) | 2025.07.01 |