라디오시티
고친 사람 github-actions[bot]
라디오시티는 방 안에서 빛이 벽과 바닥 사이를 여러 번 튕기며 퍼지는 모습을 계산합니다. 표면을 작은 조각으로 나눈 장면을 받아 조각마다 최종 밝기가 얼마인지 한꺼번에 풉니다. 한 번 풀어 두면 어느 방향에서 봐도 밝기를 다시 계산하지 않습니다. 같은 이름이 표면에서 떠나는 빛의 양을 뜻하는 물리량으로도 쓰입니다.
쉽고 빠른 이해
라디오시티는 빛이 표면 사이를 오가며 서로를 밝혀 주는 효과를 계산합니다. 창문 하나만 있는 방에서도 창이 안 비치는 구석이 새까맣지 않은 것이 이 효과입니다. 빨간 벽 옆의 흰 바닥이 살짝 붉게 물드는 것도 같은 효과입니다.
광원에서 바로 오는 빛만 계산하면 그늘진 곳은 전부 까맣게 나옵니다. 벽에 맞고 튕겨 나온 빛까지 더해야 눈에 보이는 방과 비슷해집니다.
- 장면의 표면을 작은 조각으로 나눕니다
- 조각 둘마다 서로를 얼마나 보는지 셉니다
- 「내 밝기는 내가 내는 빛 더하기 남들한테서 받아 되튕긴 빛」이라는 식을 모든 조각에 대해 한꺼번에 풉니다
대가는 둘입니다. 조각 수가 두 배가 되면 짝의 수는 네 배가 됩니다. 계산 시간도 따라 늡니다. 그리고 거울이나 광택처럼 보는 방향에 따라 달라지는 반사는 못 그립니다.
그래서 회벽이나 종이처럼 빛을 고르게 흩뿌리는 표면이 대부분인 실내에 씁니다. 밝기를 미리 계산해 그림 파일에 구워 두는 게임 조명에도 이 생각이 쓰입니다.
상세
이 절은 라디오시티가 무엇을 받아 무엇을 내놓는지, 왜 그 계산이 연립방정식 하나로 줄어드는지를 다룹니다. 서로 마주 보는 벽 두 장을 끝까지 풀어 보며 확인합니다.
넣는 것은 세 가지입니다. 표면을 조각으로 나눈 장면, 조각마다 스스로 내는 빛의 양, 조각마다 받은 빛을 되튕기는 비율입니다. 나오는 것은 조각마다의 최종 밝기입니다. 이 밝기를 표면에 칠해 두면 광원에서 바로 온 빛과 벽에 튕겨 온 빛이 모두 담긴 그림이 나옵니다.
바로 오는 빛만 세면 생기는 어둠
렌더링은 장면 정보로 화면 한 장을 그리는 일입니다. 가장 단순한 렌더링은 표면 한 점마다 광원에서 빛이 바로 닿는지만 봅니다. 직접 조명은 이렇게 광원에서 바로 닿는 빛입니다.
직접 조명만 세면 광원이 안 보이는 곳은 까맣습니다. 책상 밑, 방 구석, 문 뒤가 그렇습니다. 눈으로 보는 방은 그렇지 않습니다. 벽과 천장에 맞고 튕겨 나온 빛이 그늘까지 들어오기 때문입니다. 한 번 이상 튕겨서 오는 이 빛을 간접 조명이라고 합니다.
전역 조명은 직접 조명과 간접 조명을 함께 세는 계산입니다. 라디오시티는 그 계산법 가운데 하나입니다.
라디오시티는 이 분야에서 이른 시기에 나온 방법입니다. 열공학에는 뜨거운 물체끼리 열을 빛처럼 내뿜어 주고받는 양을 계산하는 복사 열전달 방법이 있었습니다. 라디오시티는 그 방법을 빛에 옮겨 왔습니다.
흩뿌리는 표면이라는 전제
표면이 빛을 되튕기는 방식은 크게 둘입니다. 거울이나 광택 있는 금속은 들어온 빛을 한 방향으로 튕깁니다. 이런 반사가 정반사입니다. 회벽이나 종이는 들어온 빛을 모든 방향으로 고르게 흩뿌립니다. 이것을 확산 반사라고 합니다.
확산 반사만 하는 표면은 어느 방향에서 봐도 밝기가 같습니다. 흰 회벽을 정면에서 보든 비스듬히 보든 같은 흰색인 것과 같습니다. 모든 방향으로 고르게 흩뿌리는 이상적인 표면을 램버트 반사 표면이라고 부릅니다.
라디오시티는 모든 표면이 확산 반사만 한다고 가정합니다. 이 가정 덕에 표면 조각 하나의 밝기를 숫자 하나로 적을 수 있습니다. 보는 방향을 따질 필요가 없으니 카메라가 어디 있든 답이 같습니다. 이 성질을 시점 독립이라고 합니다.
시점 독립이 주는 이점은 재사용입니다. 밝기를 한 번 풀어 두면 카메라가 방 안을 돌아다녀도 다시 풀지 않습니다. 광원과 물체가 움직이지 않는 한 그렇습니다.
표면을 조각으로 나누기
곡면이든 평면이든 표면 위의 밝기는 곳곳이 다릅니다. 컴퓨터가 이걸 다루려면 표면을 작은 조각으로 잘라 조각 안에서는 밝기가 같다고 칩니다. 이 조각을 패치라고 부릅니다.
패치를 잘게 자를수록 밝기의 변화가 매끄럽게 나옵니다. 그만큼 패치 수가 늘고 계산 시간도 늡니다. 그래서 흔히 그림자 경계처럼 밝기가 급하게 바뀌는 곳만 잘게 자르고 나머지는 크게 둡니다. 이렇게 필요한 곳만 더 나누는 일을 적응형 분할이라고 합니다.
서로를 얼마나 보나 · 형태 계수
패치 A 에서 흩뿌려진 빛 가운데 얼마가 패치 B 에 닿을까요. 이 비율을 형태 계수라고 합니다. A 에서 B 로 가는 형태 계수가 0.2 라면, A 가 내보낸 빛의 5분의 1이 B 에 떨어진다는 뜻입니다.
형태 계수는 두 패치의 모양과 배치로만 정해집니다. 두 패치가 가까울수록 커집니다. 서로 정면으로 마주 볼수록 커집니다. 둘 사이를 다른 물체가 가리면 그만큼 작아집니다. 다 가리면 0 입니다. 가려지는지 따지는 이 검사를 가시성 검사라고 합니다.
한 패치에서 나가는 형태 계수를 모두 더하면 1 을 넘지 않습니다. 패치가 흩뿌린 빛은 어딘가에 닿거나 장면 밖으로 빠져나가기 때문입니다. 닫힌 방이라면 합이 1 이 됩니다.
형태 계수는 시야로도 읽을 수 있습니다. A 에서 나간 빛 가운데 B 에 닿는 몫은, A 에 서서 둘러본 시야 가운데 B 가 차지하는 몫과 같습니다. 단 시야의 정면 쪽을 옆쪽보다 무겁게 칩니다. 흩뿌리는 표면은 옆보다 정면으로 빛을 더 많이 내보내기 때문입니다.
형태 계수를 구하는 대표적인 방법인 헤미큐브는 이 시야를 직접 셉니다. 패치 위에 반쪽짜리 정육면체를 씌웁니다. 정육면체의 면은 작은 칸이 바둑판처럼 놓인 격자입니다. 칸마다 맡은 몫이 미리 정해져 있습니다. 정면 쪽 칸일수록 몫이 큽니다.
나머지 패치들을 그 면에 그려 넣은 뒤 몇 칸을 차지하는지 셉니다. 패치 B 가 차지한 칸의 몫을 모두 더하면 A 에서 B 로 가는 형태 계수가 됩니다. 그림을 그리는 과정에서 앞의 물체가 뒤의 물체를 가리므로 가시성 검사가 함께 끝납니다.
라디오시티 방정식
패치 하나가 내보내는 빛은 두 몫을 더한 것입니다. 스스로 내는 빛과, 다른 패치들에게서 받아 되튕기는 빛입니다. 이것을 패치 i 에 대해 적으면 아래와 같습니다.
B_i = E_i + ρ_i × Σ_j ( F_ij × B_j )
각 기호의 뜻은 아래와 같습니다.
| 기호 | 뜻 | 예 |
|---|---|---|
B_i |
패치 i 가 내보내는 빛의 양. 구하려는 값 | 모른다 |
E_i |
패치 i 가 스스로 내는 빛 | 전등이면 크고, 벽이면 0 |
ρ_i |
받은 빛을 되튕기는 비율. 반사율 | 흰 벽 0.8 · 검은 천 0.05 |
F_ij |
패치 i 에서 나간 빛 가운데 패치 j 에 닿는 몫. i 의 시야에서 j 가 차지하는 몫과 같다 | 0 ~ 1 |
Σ_j |
다른 패치 j 전부에 대해 괄호 안을 더한다 |
식이 B_j 에 F_ij 를 곱하는 까닭은 앞에서 본 시야 읽기에 있습니다. 패치 i 가 받는 빛은 i 의 시야 곳곳에서 들어옵니다. 그 가운데 j 쪽에서 오는 빛은 j 의 밝기 B_j 에 i 의 시야에서 j 가 차지하는 몫 F_ij 를 곱한 만큼입니다.
식의 오른쪽 끝에 다른 패치의 B_j 가 들어 있습니다. 내 밝기가 남의 밝기에 달려 있다는 뜻입니다. 남의 밝기도 다시 내 밝기에 달려 있습니다. 그래서 패치 하나씩 따로 풀 수 없습니다.
패치가 n 개면 이런 식이 n 개 생기고 모르는 값도 n 개입니다. 곧 연립방정식 하나입니다. 이 연립방정식을 풀면 모든 패치의 밝기가 한꺼번에 나옵니다.
식의 맨 앞 B 가 이 방법의 이름이 된 물리량입니다. 물리에서 라디오시티는 표면의 단위 면적에서 1초 동안 떠나는 빛 에너지를 가리킵니다. 단위는 와트 퍼 제곱미터입니다. 스스로 내는 빛과 되튕긴 빛을 모두 포함한다는 점이 받는 빛의 양과 다릅니다.
벽 두 장으로 풀어 보기
마주 보는 벽 A 와 B 를 생각합니다. A 는 빛을 내는 판이라 스스로 10 을 냅니다. B 는 빛을 안 냅니다. 둘 다 반사율은 0.5 입니다. 서로를 보는 형태 계수도 둘 다 0.5 로 둡니다.
식을 세우면 B_A = 10 + 0.5 × 0.5 × B_B 와 B_B = 0 + 0.5 × 0.5 × B_A 입니다. 이 식을 손으로 푸는 대신 되풀이해 봅니다. 처음에는 스스로 내는 빛만 넣습니다. 그 뒤로는 바퀴마다 상대의 직전 값을 넣어 다시 계산합니다.
| 바퀴 | A | B | 이 바퀴에 더해진 빛 |
|---|---|---|---|
| 0 | 10 | 0 | A 가 스스로 낸 빛 |
| 1 | 10 | 2.5 | A 의 빛이 B 에 한 번 닿아 튕겼다 |
| 2 | 10.625 | 2.5 | B 에서 튕긴 빛이 A 로 돌아왔다 |
| 3 | 10.625 | 2.656 | 한 번 더 왕복했다 |
| 4 | 10.664 | 2.656 | |
| 끝 | 10.667 | 2.667 | 더 돌려도 셋째 자리까지 안 바뀐다 |
표를 위에서 아래로 읽으면 빛이 튕기는 순서와 겹칩니다. 바퀴가 하나 늘 때마다 빛이 한 번 더 튕긴 몫이 더해집니다. 아무것도 안 하면 까맣던 B 가 2.667 만큼 밝아졌습니다. 이것이 간접 조명입니다.
더해지는 몫은 바퀴마다 4분의 1로 줄어듭니다. 4분의 1은 형태 계수 0.5 와 반사율 0.5 를 곱한 값입니다. 한 벽이 내보낸 빛은 절반만 상대 벽에 닿고 나머지는 빠져나갑니다. 닿은 빛도 절반은 흡수되고 절반만 튕깁니다.
몇 바퀴만 돌아도 답이 굳는 것은 이렇게 빛이 빠르게 줄기 때문입니다.
연립방정식을 푸는 두 방법
식끼리 더하고 빼서 모르는 값을 하나씩 없애는 풀이를 소거법이라고 합니다. 연립방정식을 소거법으로 단번에 풀면 계산이 패치 수의 세제곱으로 늘어납니다. 패치가 수천 개만 돼도 감당하기 어렵습니다. 그래서 위 표처럼 되풀이로 다가가는 반복법을 씁니다.
바퀴마다 모든 패치를 새로 계산하면서 방금 바뀐 값을 바로 다음 패치 계산에 넣는 방식이 가우스-자이델 방법입니다. 패치마다 「남들한테서 빛을 모아 오는」 셈이라 모으기 방식이라고도 부릅니다. 한 바퀴를 다 돌아야 화면 전체가 한 단계 밝아집니다.
반대 방향의 방식도 있습니다. 이 방식은 패치마다 받았지만 아직 남에게 나눠 주지 않은 빛을 따로 적어 둡니다. 처음에는 광원만 이 빛을 가집니다. 한 패치가 이 빛을 다른 패치들에 나눠 주면 그 패치의 몫은 0 이 되고, 받은 패치들의 몫에 쌓입니다.
차례마다 아직 나눠 주지 않은 빛이 가장 많은 패치 하나를 골라 그 빛을 다른 모든 패치에 나눠 줍니다. 방금 나눠 준 패치는 몫이 0 이라 바로 다시 뽑히지 않습니다. 이것을 점진적 정제라고 합니다. 뿌리기 방식이라고도 부릅니다.
점진적 정제의 이점은 중간 결과입니다. 아직 나눠 주지 않은 빛이 가장 많은 패치부터 뿌리므로 처음 몇 번만 뿌려도 전체 밝기의 큰 몫이 화면에 나옵니다. 사용자는 대강의 그림을 먼저 보고, 뿌리기가 이어질수록 그림이 다듬어집니다.
뿌리기 방식으로 한 장면을 푸는 흐름을 그리면 아래와 같습니다.
flowchart TD
A["장면의 표면을 패치로 나눈다"] --> C["아직 나눠 주지 않은 빛이 가장 많은 패치를 고른다"]
C --> B["그 패치에서 나가는 형태 계수를 구한다"]
B --> D["그 빛을 다른 패치들에 형태 계수만큼 나눠 준다"]
D --> E{"아직 나눠 주지 않은 빛이 모든 패치에서 충분히 작은가"}
E -->|아니다| C
E -->|그렇다| F["패치마다 밝기를 칠해 둔다"]
F --> G["카메라가 움직여도 칠한 밝기로 그린다"]
뿌리기 방식에서는 고른 패치 하나에서 나가는 형태 계수만 있으면 됩니다. 형태 계수를 미리 전부 저장해 두지 않고 차례가 올 때마다 그 패치 몫만 계산해도 됩니다.
계산량
패치 수를 n 이라고 하면 비용은 대부분 형태 계수에서 나옵니다. 짝이 n × n 개이기 때문입니다. 짝마다 가시성 검사도 들어갑니다.
O 표기는 입력이 커질 때 비용이 어떤 꼴로 늘어나는지를 나타냅니다. O(n²) 이면 n 이 두 배가 될 때 비용이 네 배가 됩니다. 이 표기를 빅오 표기법이라고 합니다. 일마다 드는 시간과 공간을 이 표기로 적으면 아래와 같습니다.
| 일 | 시간 | 공간 |
|---|---|---|
| 형태 계수 전부 구하기 | O(n²) 짝 · 짝마다 가시성 검사 | 전부 저장하면 O(n²) |
| 소거법으로 단번에 풀기 | O(n³) | O(n²) |
| 반복법 한 바퀴 | O(n²) | O(n²) |
| 점진적 정제 한 번 뿌리기 | O(n) 형태 계수 계산 포함 | O(n) |
제곱이 어느 정도인지 수로 짚어 봅니다. 패치가 1만 개면 짝은 1억 개입니다. 짝마다 형태 계수 하나를 4바이트로 담아도 400메가바이트입니다. 패치를 잘게 나눌수록 그림은 좋아지지만 이 수가 빠르게 불어납니다.
반복법이 몇 바퀴 만에 끝나는지는 반사율에 달려 있습니다. 반사율이 낮으면 튕길 때마다 빛이 많이 줄어 몇 바퀴면 끝납니다. 흰 벽으로 둘러싸인 방처럼 반사율이 높으면 빛이 오래 살아남아 바퀴가 늘어납니다.
못 그리는 것
첫째는 정반사입니다. 거울에 비친 모습, 광택 있는 바닥의 반짝임, 유리를 지나며 휘는 빛은 라디오시티로 못 그립니다. 패치마다 밝기를 숫자 하나로만 들고 있기 때문입니다. 방향에 따라 달라지는 빛은 담을 데가 없습니다.
그래서 흔히 두 방법을 섞습니다. 확산 반사는 라디오시티로 미리 풀어 둡니다. 거울과 광택은 그릴 때 광선 추적으로 따로 계산합니다. 광선 추적은 눈에서 광선을 쏘아 무엇에 맞는지 따라가는 방법입니다.
둘째는 패치 경계가 드러나는 문제입니다. 패치 안에서는 밝기가 같다고 쳤으므로 패치가 크면 밝기가 계단처럼 끊겨 보입니다. 그림자 경계가 흐릿해지거나, 벽과 바닥이 만나는 모서리에서 빛이 새어 나온 것처럼 보이기도 합니다. 그래서 그릴 때 이웃 패치의 밝기를 섞어 부드럽게 칠합니다. 경계 부근은 패치를 더 잘게 나눕니다.
셋째는 움직임입니다. 광원이나 물체가 움직이면 형태 계수와 밝기가 바뀌므로 다시 풀어야 합니다. 시점 독립은 카메라에만 해당합니다.
쓰는 곳과 고르는 기준
라디오시티가 잘 맞는 곳은 확산 반사가 대부분인 실내입니다. 건물을 짓기 전에 방이 얼마나 밝을지 미리 보는 조명 설계가 대표적입니다. 결과가 카메라 위치와 무관하므로 한 번 풀어 두고 방 안을 돌아다니며 볼 수 있습니다.
게임에서는 밝기를 미리 계산해 그림 파일에 구워 두는 라이트맵 베이킹에 이 생각이 쓰입니다. 실행 중에는 구워 둔 밝기를 읽기만 하므로 간접 조명을 공짜에 가깝게 얻습니다.
같은 전역 조명 문제를 푸는 다른 방법과 견주면 이렇습니다.
| 방법 | 무엇을 계산하나 | 잘하는 것 | 못하는 것 |
|---|---|---|---|
| 라디오시티 | 패치마다의 밝기를 연립방정식으로 | 시점이 바뀌어도 재사용 · 부드러운 간접 조명 | 정반사 · 움직이는 장면 |
| 패스 트레이싱 | 눈에서 쏜 광선이 무작위로 튕기는 길 | 정반사와 확산 반사를 함께 | 광선이 적으면 화면이 자글자글하다 · 시점마다 다시 계산 |
| 포톤 매핑 | 광원에서 뿌린 빛 알갱이가 쌓인 곳 | 유리나 물을 지난 빛이 모이는 무늬 | 알갱이를 담을 메모리 |
관련 항목
라디오시티가 속하는 상위 분류
전역 조명 · 렌더링 · 그래픽스 · 물리 기반 렌더링 · 렌더링 방정식
같은 전역 조명 문제를 두고 겨루는 계산법
패스 트레이싱 · 광선 추적 · 양방향 패스 트레이싱 · 포톤 매핑 · 분산 광선 추적 · 화면 공간 전역 조명 · 몬테카를로 방법
라디오시티를 이루는 구성 요소
패치 · 형태 계수 · 헤미큐브 · 가시성 · 적응형 분할 · 메시
라디오시티가 전제하는 반사와 빛의 성질
확산 반사 · 램버트 반사 · 정반사 · 반사율 · 직접 조명 · 간접 조명 · 색 번짐 · BRDF
라디오시티 방정식을 푸는 수치 방법
연립방정식 · 반복법 · 가우스-자이델 방법 · 야코비 방법 · 가우스 소거법 · 점진적 정제
라디오시티의 결과를 담아 쓰는 기법
라이트맵 · 베이킹 · 구로 셰이딩 · 앰비언트 오클루전
라디오시티가 빌려 온 물리량과 이론
복사 열전달 · 복사 조도 · 복사 휘도 · 측광 · 빅오 표기법
다른 이름: radiosity · 래디오시티 · 라디오시티 방법 · radiosity method