조명 모델은 다음과 같이 두 가지로 구분된다.
- 지역 조명(local illumination)
- 전역 조명(global illumination)
퐁 모델은 지역 조명 모델인데, 조명 대상인 물체의 표면 재질과 광원의 속성만 이용해 해당 표면의 색상을 결정할 뿐, 같은 공간에 있는 다른 물체는 고려하지 않는다.
(a)를 보면, 퐁 모델로 $S_2$를 라이팅 할 때, $S_1$은 전혀 고려되지 않는다.
따라서 마치 $S_1$이 존재하지 않는 것처럼 $S_2$는 빛을 받는다. 퐁 모델은 물리학적으로 올바르지 않은 모델이다.
(b)처럼 $S_2$가 전혀 빛을 받지 못하는 것으로 처리하는 것도 올바른 방법은 아니다.
광원으로부터 나오는 빛이 $S_2$에는 직접 닿지 못해도, 공간 내 다른 물체에 반사되어 $S_2$로 들어올 수 있기 때문이다. 퐁 모델의 앰비언트 항은 이러한 간접 조명(indirect lighting)을 담당한다.
하지만, 이는 과도하게 단순화되어 있어서 사실적인 영상을 만들지 못한다.
간접 조명 효과를 담아내기 위하여 전역 조명 모델은 장면의 모든 물체를 잠재적인 광원으로 취급한다.
(c)에서 $S_2$는 $S_1$과 $S_3$로부터 간접 조명을 받는다.
$S_2$의 왼편은 $S_3$로부터 간접 조명에 의해 상대적으로 밝게 보인다.
마찬가지로, $S_1$의 아래 부분 역시 직접 조명을 전형 못 받지만 약간 밝게 보인다.
그런데, 전역 모델은 많은 연산을 필요로 하므로 실시간에 구현하기 쉽지 않다. ex) 영화 특수 효과 → 한 프레임 몇 시간씩
상용 게임을 비롯한 실시간 그래픽스 영역에서는 간략화된 전역 조명 알고리즘을 사용하거나, 혹은 전처리 단계에서 전역 조명을 미리 계산하여 저장한 뒤 런타임에 이를 이용하는 것이 주요 흐름으로 자리 잡았다. 여기서 텍스처는 매우 중요한 역할을 한다.
16.1 전역 조명 모델
컴퓨터 그래픽스 역사 초기에 제안된 전역 조명 기법은 광선 추적법(ray tracing)과 래디오시티(radiosity)이다.
이들은 현재에도 널리 상용되고 있다.
16.1.1 광선 추적법
뷰 프러스텀은 카메라가 수렴하는 투영선(projection line)의 집합이다.
투영선의 개수는 스크린 영상의 해상도와 같고, 투영선 하나가 픽셀 하나의 색상을 결정한다.
위 그림은 8 x 6 해상도의 영상을 보여준다(편의를 위해 위쪽과 오른쪽 테두리의 투영선만 그림).
각 투영선 반대 방향(카메라에 각 픽셀을 향해)으로 광선(ray)을 발사한 뒤 이를 추적하여 해당 투영선을 따라 들어오게 될 색상을 계산한다. 이것이 픽셀 색상이 된다. 이렇게 투영선 역방향으로 발사되는 광선을 1차 광선(primary ray)이라 부른다.
1차 광선이 물체와 부딪혔을 때, 세 개의 2차 광선(second ray)이 생성된다.
- 그림자 광선(shadow ray)
- 반사 광선(reflection ray)
- 굴절 광선(refraction ray 혹은 transmitted ray)
그림자 광선(shadow ray)
1차 광선이 어떤 물체와 부딪혔을 때, 그 교차점이 그림자 안에 있는지 검사하기 위해 각 광원을 향해 발사하는 광선이다.
1차 광선은 커다란 구와 $p_1$에서 교차했는데, 여기에서 그림자 광선 $s_1$이 광원을 향해 발사되었다.
만약 $s_1$이 광원으로 가는 도중 다른 물체와 부딪히면 $p_1$은 광원의 직접적인 영향권에 있지 않으며 그림자 영역에 놓인 것으로 판정한다. 위 그림에 해당한다.
반면, $s_1$이 광원에 도달하게 되면, 이 광원으로부터 $p_1$에 입사하는 빛을 이용해 $p_1$의 직접 조명 색상을 결정한다. 이를 위해 퐁 모델을 쓸 수 있다.
반사 광선(reflection ray)
1차 광선이 $p_1$의 노멀 $n_1$을 중심으로 반사된 것이다. 1차 광선은 $I_1$으로, 반사 광선은 $r_1$으로 표기한다.
$I_1$의 입사각과 $r_1$의 반사각이 같다는 성질을 이용하여 $r_1$의 방향은 다음과 같이 구해진다.
$I_1 - 2n_1\left(n_1 \cdot I_1 \right)$
굴절 광선(refraction ray 혹은 transmitted ray)
1차 광선이 반투명한 물체와 부딪힐 때 발생하는 광선이다.
$I_1$에 의해 발생된 굴절 광선을 $t_1$으로 표기하면, $t_1$의 방향은 굴절의 법칙에 따라 정해진다.
광선 추적법은 재귀적인(recursive) 알고리즘이다.
즉, 그림에서 $r_1$과 $t_1$은 마치 이들이 1차 광선인 것처럼 다시 추적된다.
$r_1$은 불투명한 물체의 점 $p_2$에 부딪혀서 그림자 광선 $s_2$와 반사 광선 $r_2$를 생성한다(불투명한 물체와 부딪혔으므로 굴절 광선은 생성되지 않는다).
$s_2$가 광원에 도달하므로, 이 광원을 이용하여 $p_2$의 직접 조명 색상을 결정한다.
동시에, $r_2$는 $r_1$과 같은 방식으로 재귀적으로 추적된다.
한편, $t_1$은 반투명한 물체의 점 $p_3$에 부딪혀서 세 개의 2차 광선$\left(s_3, r_3, t_3 \right)$을 생성한다.
광선 추적법 알고리즘의 재귀적인 구조는 위 사진의 좌측처럼 광선 트리(ray tree)로 설명할 수 있다.
이 광선 트리는 반사/굴절 광선이 어떤 물체에도 부딪히지 않고 장면을 벗어날 때까지 또는 미리 정의된 재귀 단계에 도달할 때까지 확장된다.
광선 트리의 노드 $p_3$을 보면, $r_3$를 추적해서 얻은 색상은 $p_3$의 스페큘러 계수와 곱해지고, $t_3$를 추적해서 얻은 색상은 $p_3$의 투과율(transmission coefficient)과 곱해진다.
이 둘은 $s_3$를 통해서 계산된 직접 조명 색상에 더해지고, 그 결과는 부모 노드인 $p_1$으로 전달된다.
광선 트리의 모든 노드에서 이와 같은 작업이 재귀적으로 진행되면 최종적으로 루트 노드에서의 색상을 얻을 수 있다.
이것이 1차 광선이 부딪힌 점의 색상이다($p_1$의 색상 의미).
아래 사진은 광선 추적법으로 얻은 극사실적인 영상이다.
참고
굴절 광선
위 그림은 성질이 상이한 두 개의 매체를 통과하는 빛을 보여준다.
$\eta$는 매체의 굴절률(refracttive index)을 의미하는데, 진공 상태에서는 1.0이고 물에서는 1.3이다.
노멀 $n$을 기준으로 입사 벡터 $I$가 생성하는 입사각은 $\theta_I$로, 굴절 벡터 $t$가 생성하는 굴절각은 $\theta_t$로 표기했다. 굴절 벡터 계산을 위해 스넬의 법칙(Snell's law)을 이용한다.
16.1.2 래디오시티 알고리즘
래디오시티(radiosity) 알고리즘은 디퓨즈 표면을 가진 물체들 사이에서 반사되는 빛을 계산한다.
표면에 부딪힌 빛은 반사되어 다른 물체를 비추게 되므로, 장면을 구성하는 모든 표면은 광원과 같은 역할을 한다.
즉, 래디오시티 알고리즘은 광원과 이것에 의해 조명되는 물체를 구분하지 않는다.
래디오시티를 이용한 전역 조명을 구현하기 위해서는 먼저 장면 내 존재하는 모든 표면을 잘게 나눠 패치(patch)들을 만든다.
그 다음, 패치 사이의 형태 인자(form factor)를 계산한다. 이는 한 패치에서 다른 패치가 얼마만큼 보이는지 계산한 것인데, 두 패치 간 거리 및 각 패치의 방향에 좌우된다.
만약 패치 간 거리가 크고, 패치가 서로 장면을 보지 않고 기울어져 있다면 형태 인자는 작은 값을 가진다.
한 패치의 래디오시티는 그 패치로부터 나오는 빛의 속도라고 정의되는데, 그 패치가 직접 빛을 발사하는 속도에 그 패치가 빛을 발사하는 속도를 더한 것으로 결정된다.
$B_i = E_i + r_i \sum_{j=1}^n f_{i,j}B_j$
$B_i$와 $B_j$는 각각 패치 $p_i$와 $p_j$의 래디오시티이고, $E_i$는 패치 $p_i$의 초기 래디오시티, $r_i$는 패치 $p_i$의 반사 계수, $f_{i,j}$는 형태 인자이다. 광원이 아닌 경우, $E_i$는 0이 된다.
이 식에서 $ \sum_{j=1}^n f_{i,j}B_j $는 패치 $p_i$에 들어오는 빛(irradiance)을 말한다. 식을 다음과 같이 고칠 수 있다.
$ B_i - r_i \sum_{j=1}^n f_{i,j}B_j = E_i $
장면의 모든 패치에 위 식을 적용하면 다음과 같은 선형 시스템(linear system)을 얻을 수 있다.
이를 풀면 모든 패치의 래디오시티를 구할 수 있다.
위 사진에서 두 패치 $p_i$와 $p_j$ 각각은 미분 면적(differential area) $dA$와 표면 노멀 $N$을 가지고, $dA_i$와 $dA_j$를 잇는 벡터는 $v$로 표기했다.
$N_i$와 $v$ 사이의 각도를 $\theta_i$로, $N_j$와 $-v$ 사이의 각도를 $\theta_j$로 표기하면, $dA_i$와 $dA_j$ 간 형태 인자는 다음과 같이 정의된다.
$\alpha$는 $dA_i$와 $dA_j$ 간 가시성(visibility)을 의미한다.
만약 $dA_i$에서 $dA_j$를 볼 수 있다면 $\alpha$는 1이고 그렇지 않으면 0이다.
한편 $dA_i$에서 $dA_j$를 볼 수 있다면 $dA_j$에서도 $dA_i$를 볼 수 있다.
위의 수식은 점과 점 사이의 형태 인자를 정의하므로, 두 패치 $p_i$와 $p_j$ 사이의 형태 인자를 계산하기 위해서는 적분해야 한다.
그런데, 한 패치의 모든 점에서 래디오시티가 일정하다고 가정하면, 패치와 패치 간 형태 인자 계산은 점과 패치 간 형태 인자 계산으로 대체될 수 있다.
$p_i$의 대표점을 $q$라 하자($q$는 $p_i$ 표면의 중앙점일 수 있다).
$q$와 $p_j$ 사이의 형태 인자를 계산하기 위해 (a)에 보인 것처럼 $q$에 반구(hemisphere)를 올려놓았다(반구의 축 $N_i$는 $q$에서의 표면 노멀과 같다).
$q$에서 $p_j$가 완전하게 보인다고 가정하면, 형태 인자를 계산하기 위해서는 $p_j$를 먼저 반구 표면에 투영하고 그 결과를 다시 반구 바닥에 투영한다.
투영된 $p_j$의 면적이 반구의 바닥면에서 차지하는 비율이 형태 인자가 된다(독일 과학자 Wilhelm Nusselt에 의해 제안된 기법).
이제 형태 인자를 이용해 선형 시스템을 풀 수 있다. 다음은 래디오시티 알고리즘으로 렌더링한 사진이다.
실제 래디오시티 알고리즘 구현을 위해서는 다양한 최적화 기법이 사용된다.
간단한 기법 중 하나는 반구를 반정육면체(hemicube)로 대체하는 것이다.
반정육면체의 다섯 개 면은 각각 픽셀의 2차원 배열로 구성되고, 각각의 픽셀은 정사각형 영역을 차지한다.
$q$와 픽셀 간 형태 인자는 반정육면체에서 그 픽셀이 어디에 위치하는가에 따라 달라진다.
예를 들어, $N_i$축에 가까이 놓인 픽셀은 반정육면체의 모서리에 놓인 픽셀보다 큰 형태 인자를 가지게 된다.
이러한 '픽셀별 형태 인자'는 미리 계산된다.
$p_j$를 반정육면체 표면에 투영해보면, $q$와 $p_j$간 형태 인자는 $p_j$가 투영된 영역에 속하는 픽셀들의 형태 인자들의 합으로 정의된다.
특히 z-버퍼링 알고리즘을 사용하면 $q$에서의 $p_j$ 가시성도 동시에 처리할 수 있다
래디오시티 알고리즘은 실시간에 구현하기에 연상량이 너무 많다. 따라서 실시간 그래픽스의 경우, 보통 전처리 단계에서 이를 실행하여 $\sum_{j=1}^n f_{i,j}B_j$를 텍스처에 저장한 후, 런타임에 이 텍스처를 사용한다. 이러한 텍스처를 라이트맵(light map)이라고 부른다.
16.2 라이트 매핑
물체와 광원이 모두 고정되어 있는 공간을 걸어 다닌다고 가정한 것이 위 사진이다.
시긱향 벽면을 스포트라이트(spot light)가 비추고 있는 상태에서 카메라가 왼쪽에서 오른쪽으로 움직였다.
벽이 흰색 디퓨즈 표면이고 광원 역시 흰색이라고 가정하면, 카메라에 잡히는 벽의 색상은 회색조이다. 이는 바로 디퓨즈 반사 색상이다. 그런데, 벽면의 디퓨즈 반사 색상은 카메라 위치에 관계없이 일정하다.
퐁 모델의 디퓨즈 항 $max\left( n \cdot l, 0 \right)s_d \bigotimes m_d$를 사용해 라이트 매핑의 개념을 설명한다. $max\left( n \cdot l, 0 \right)s_d$는 물체로 들어오는 빛(irradiance)을 말하는데, 물체와 광원이 모두 고정되어 있다면 이는 변하지 않으므로 이를 미리 계산하여 텍스처에 저장할 수 있다. 이 텍스처를 라이트맵(light map)이라 부른다.
런타임에 별다른 계산을 하지 않으므로 런타임 성능이 향상된다.
한편, 라이트맵은 대체로 이미지 텍스처보다 낮은 해상도를 가진다.
물체 표면에서 디퓨즈 색상의 변화는 대체로 완만하므로 저해상도로 넓은 표면 영역을 표현하는 것이 가능하기 때문이다.
라이트 매핑은 런타임 성능만 향상시키는 것이 아니다.
라이트맵은 전처리 단계에서 생성되므로 충분한 시간을 가지고 만들 수 있다.
따라서 연산량이 많은 고급 조명 모델을 사용할 수 있다.
대부분의 라이트맵은 래디오시티 알고리즘을 통해 만들어진다.
따라서 라이트 매핑된 장면은 지역 조명으로 처리된 것보다 높은 품질의 영상을 보여준다.
라이트 맵을 만드는 방식은 노멀맵 제작 방식과 유사하다.
라이트 매핑이 적용될 표면을 파라미터화한 다음 텍스처 공간에서 스캔 전환한다.
이렇게 생성된 각 텍셀에 해당하는 물체 표면의 점을 구하고 여기에 들어오는 빛을 계산한다.
계산된 값은 텍스처에 저장되는데, 이것이 바로 라이트맵이다.
16.3 환경 매핑
환경 매핑(environment mapping)
- 주변 환경을 반사하는 매끄러운 물체를 렌더링하는 기법
- 환경맵(environment map)이라고 불리는 텍스처에 주변 환경의 영상을 담아야 한다.
16.3.1 큐브 매핑
큐브맵(cube map)은 가장 많이 쓰이는 환경맵이다.
그림 (a) 가상의 정육면체, 그리고 그 중심에 위치한 카메라를 보여준다.
이 정육면체의 여섯 개 면 각각을 향해서 수직과 수평 방향으로 모두 $90^{\circ}$의 시야각(field of view)을 설정해 사진을 찍거나 렌더링을 수행하면 여섯 개의 정사각형 이미지를 얻을 수 있다.
이를 정육면체에 붙여 놓은 것을 큐브맵이라고 보면 된다.
개념적으로 큐브맵은 물체를 감싸는 것으로 간주할 수 있다.
물체 표면의 점 $p$가 주변 환경을 반사하도록 만들기 위해서, 카메라로부터 $p$를 향해 광선 $I$를 발사하고 이를 추적한다.
$I$는 $p$의 노멀 $n$을 기준으로 반사되어 $R$이라는 벡터를 결정한다.
$R$을 정의하는 수식은 전역 조명을 위한 광선 추적법에서 반사 광선의 반사각의 방향을 구하는 수식과 같다.
$R$은 큐브맵의 한 면과 교차하는데, 이 교차점을 이용해 해당 면의 이미지 텍스처를 필터링한다.
예를 들어, 교차점 주변의 네 개의 텍셀을 겹선형보간하는 것이다. 이 결과가 바로 $p$에서 반사되는 색상을 결정한다.
이러한 큐브 매핑은 간략화된 광선 추적법이라 부를 수 있는데, 2차 광선 중 반사 광선만 추적이 되고 재귀적인 과정도 거치지 않기 때문이다(딱 한 번만 반사된다).
전역 조명이라고 말 할 수는 없지만, 지역 조명에서 조금 벗어난 정도이다. 오목한 부분은 자기 자신을 반사하지 않는 문제가 있기 때문이다. 주전자 주둥이가 몸통에 반사되어 보여야 되는데, 없는 것을 보면 알 수 있다.
각 면은 축이 향하는 방향으로 이름이 지어진다.
GL에서 6개 면에 대한 심볼릭 상수는 GL_TEXTURE_CUBE_* 로 예약되어있는데, *는 POSITIVE_X, NEGATIVE_X, POSITIVE_Y, 등이다.
이것들은 unsigned 정수 ID 이다.
GL_TEXTURE_CUBE_MAP_POSITIVE_X부터 시작하여 연속으로 1을 더하여 접근한다.
또, GL_TEXTURE_CUBE_MAP_NEGATIVE_X + 1 = GL_TEXUTRE_CUBE_MAP_POSITIVE_Y 등의 관계가 성립한다.
16.3.2 큐브 매핑을 위한 GL 프로그램과 쉐이더
큐브맵 생성을 위한 GL 프로그램
큐브맵도 텍스처의 한 종류다.
모든 텍스처 오브젝트 생성에 필요한 glGenTextures와 glBindTextures가 호출된다. 마지막으로 glTexImage2D로 텍스처 정보를 제공한다.
반복문에서는 texData에 저장된 여섯 개의 이미지를 큐브맵 텍스처의 여섯 면에 하나씩 glTexImage2D를이용해 채워간다.
큐브 매핑을 위한 정점 쉐이더
위 코드는 라이팅에서 사용한 정점 쉐이더를 간략화해서 텍스처링을 제외한 큐브 매핑 코드로 바꾸었다.
큐브 매핑을 위한 프래그먼트 쉐이더
v_normal과 v_view를 정규화하여 각각 normal과 view라고 부른다.
view의 방향은 코드 옆의 그림에서의 I의 방향과 반대이다. 즉, $I$ = -view이다.
따라서 $I$ 대신 -view를 넣어서 refl을 구한다.
16.4 앰비언트 오클루전
퐁 모델의 앰비언트(ambient reflection) 항 $s_d \bigotimes m_a$는 간접 조명을 담당하는데, 표면상의 한 점을 향해 모든 방향에서 고루 앰비언트 빛이 들어온다고 가정한다.
하지만, 특정한 방향으로는 앰비언트 빛이 들어올 수 없는 경우가 있다.
위 사진의 좌측에서 $p_1$과 $p_2$를 비교해 보면, $p_1$으로 들어오는 앰비언트 빛은 아무 방해를 받지 않지만, $p2$로 들어오는 앰비언트 빛은 물체의 다른 부분에 일부 가려진다.
앰비언트 오클루전(ambient occlusion)
- 앰비언트 빛이 가려지는 정도인 차폐도(occlusion degree)를 계산하고 이를 이용해 앰비언트 항 $s_a \bigotimes m_a$의 값을 조절하는 기법
$p_2$의 차폐도는 $p_1$보다 크므로 $p_1$보다 앰비언트 빛을 적게 받고, 결구 앰비언트 반사를 적게 한다.
위 사진의 우측 처럼 $p_2$에 반구(hemisphere)를 놓으면, 반구의 중심축은 $p_2$의 표면 노멀과 같다.
차폐도 계산을 위해, 반구 표면을 균일하게 샘플링하고 $p_2$에서 샘플점으로 광선을 발사한다.
광선 중 일부는 물체와 충돌한다. 발사된 모든 광선 중 이렇게 물체와 부딪히는 광선이 차지하는 비율이 차폐도이다.
즉 $p_2$를 보면, 광선 중 절반이 물체와 충돌하므로 차폐도는 0.5가 된다. 따라서 50%의 앰비언트 빛이 가려진다.
이렇게 광선을 사용하면 비용이 많이 드는 문제가 있다.
위 사진의 좌측을 보면, $p_2$에 놓인 반구는 빈 공간과 채워진 공간으로 구분될 수 있고, 차폐도는 전체 반구 공간에서 채워진 공간이 차지하는 비율로 근사될 수 있다.
채워진 공간의 부피를 계산하는 것은 어려우므로, 위 사진의 우측처럼 반구에 고르게 샘플 점을 뿌리고 이들이 빈 공간에 있는지 아니면 채워진 공간에 있는지 검사하도록 한다.
효율적으로 구현하기 위해 먼저 렌더링할 장면의 깊이맵을 생성한다.
위 사진에서 물체 표면의 굵은 선(노란색 굵은 선을 말함)은 카메라가 볼 수 있는 부분을 나타낸다.
표면의 스크린 공간 깊이(z) 값이 깊이맵에 저장된다.
위 사진 우측의 두 샘플 $s_1$, $s_2$를 비교해 보면, $s_1$의 스크린 공간 깊이 $d_1$은 깊이맵에 저장된 $z_1$보다 작으므로, $s_1$은 빈 공간에 속한 것으로 판정한다(쉐도우 매핑 알고리즘의 깊이 비교와 매우 유사).
반면, $s_2$의 경우는 $d_2$가 $z_2$보다 크므로 채워진 공간에 속한 것으로 판정된다.
위 사진의 우측에서 여덟 개의 샘플 중 세 개가 채워진 공간에 속한 것으로 판정되므로 $p_2$의 차폐도는 $\frac{3}{8}$으로 판정된다.
위 사진을 보면, 앰비언트 오클루전이 물체 표면의 음영을 얼마나 잘 표현하는지 확인할 수 있다.
그러나 앰비언트 오클루전은 스크린 공간에서 근사적인 계산을 수행하므로 몇 가지 문제점을 가지고 있다.
예를 들어, 뷰 프러스텀 밖에 위치한 물체는 고려하지 않는다. 따라서 오류가 발생할 수 있다.
또, 위 사진처럼 차폐도 계산에 오류가 발생할 수 있다.
하지만 다행히 이런 오류는 일반 사용자들 눈에는 거의 발견되지 않는다. 따라서 앰비언트 오클루전 알고리즘은 게임 등에서 널리 사용된다.
출처
[OpenGL ES를 이용한 3차원 컴퓨터 그래픽스 입문]을 보고 공부하고 정리한 내용
'공부 > 컴퓨터 그래픽스' 카테고리의 다른 글
OpenGL ES를 이용한 3차원 컴퓨터 그래픽스 입문 Chapter 18 GPU 테썰레이션 (0) | 2024.07.19 |
---|---|
OpenGL ES를 이용한 3차원 컴퓨터 그래픽스 입문 Chapter 17 매개변수 곡선과 곡면 (0) | 2024.07.19 |
OpenGL ES를 이용한 3차원 컴퓨터 그래픽스 입문 Chapter 15 쉐도우 매핑 (0) | 2024.07.19 |
OpenGL ES를 이용한 3차원 컴퓨터 그래픽스 입문 Chapter 14 노멀 매핑 (0) | 2024.07.19 |
OpenGL ES를 이용한 3차원 컴퓨터 그래픽스 입문 Chapter 13 캐릭터 애니메이션 (0) | 2024.07.19 |