물리 기반 셰이딩
고친 사람 github-actions[bot]
물리 기반 셰이딩은 3차원 장면을 화면에 그릴 때, 물체 표면의 색을 빛의 물리 법칙에 맞춰 계산합니다. 재질을 눈대중으로 고른 숫자가 아니라 표면의 실제 성질로 적어 둡니다. 그래서 한 번 정한 재질이 밝은 한낮에도 어두운 방에도 그럴듯하게 보입니다.
쉽고 빠른 이해
게임이나 영화는 3차원 장면을 화면에 그릴 때 물체 표면마다 색을 계산합니다. 물리 기반 셰이딩은 표면이 빛을 얼마나 튕기는지를 현실에 가깝게 계산해 그 색을 냅니다. 금반지라면 「금속이다」와 「매끈하다」만 정해 두면 반짝임의 크기와 색이 계산으로 나옵니다.
옛 방식은 반짝임의 세기와 크기를 화면을 보며 손으로 맞췄습니다. 한 조명에서 맞춘 값이 다른 조명에서는 번쩍이거나 흐려져서, 장면마다 다시 맞춰야 했습니다.
어떻게 도나:
- 재질을 바탕색, 금속인지 아닌지, 거친 정도로 적습니다
- 빛을 표면 겉에서 튕기는 몫과 안으로 들어갔다 나오는 몫으로 나눕니다
- 두 몫을 더해도 들어온 빛보다 밝아지지 않게 계산합니다
대가는 계산량과 준비물입니다. 점마다 하는 계산이 옛 방식보다 늘어납니다. 조명도 실제 밝기에 맞춰 넣어야 제대로 보입니다.
상세
셰이딩은 물체 표면의 점마다 화면에 보일 색을 계산하는 일입니다. 물리 기반 셰이딩은 이 계산을 빛의 물리 법칙에 맞춰 합니다.
표면이 빛을 받는 성질을 재질이라고 합니다. 물리 기반 셰이딩은 재질을 눈대중으로 고른 숫자가 아니라 표면의 실제 성질을 나타내는 값으로 적습니다.
재질 값이 조명과 따로 서 있다는 것이 핵심입니다. 같은 재질을 한낮 장면에서 밤 장면으로 옮겨도 값을 다시 만질 필요가 없습니다. 조명만 바뀌고 계산이 나머지를 맞춥니다.
셰이딩과 렌더링이라는 두 이름
이 방식은 PBR(Physically Based Rendering, 물리 기반 렌더링)이라는 이름으로 더 자주 불립니다. 렌더링은 3차원 장면을 화면 한 장으로 옮기는 일 전체입니다.
엄밀히 가르면 PBR 은 조명과 카메라까지 물리에 맞추는 넓은 말입니다. 물리 기반 셰이딩(PBS, Physically Based Shading)은 그중 표면의 색을 내는 계산입니다. 실무에서는 둘을 거의 같은 뜻으로 섞어 씁니다.
옛 방식이 곤란했던 까닭
물리 기반 셰이딩 전에 흔히 쓰던 계산은 퐁 반사 모델입니다. 이 모델은 표면의 밝기를 세 가지로 나눠 따로 계산한 뒤 더합니다.
| 항 | 무엇인가 |
|---|---|
| 주변 밝기 | 광원을 직접 받지 않는 곳에도 주변에서 고르게 들어오는 밝기 |
| 무광 명암 | 광원을 향한 쪽은 밝고 등진 쪽은 어두운, 윤기 없는 명암 |
| 반짝임 | 광원이 비쳐 표면에 하얗게 맺히는 밝은 점 |
반짝임의 크기와 세기는 만드는 사람이 화면을 보며 숫자로 정했습니다. 이 숫자에는 물리적 뜻이 없습니다. 반짝임 세기를 올리다 보면 표면이 들어온 빛보다 많은 빛을 내보내게 됩니다. 현실에는 없는 일이라 밝은 조명 아래에서 표면이 하얗게 타 버립니다.
그래서 한 조명에 맞춘 재질이 다른 조명에서는 어색해졌습니다. 한낮 장면에 맞춘 반짝임이 어두운 실내에서는 너무 번쩍이거나 흐릿해지는 식입니다. 장면이 바뀔 때마다 재질 값을 다시 만져야 했습니다.
물리 기반 셰이딩은 이 수작업을 줄이려고 나왔습니다. 재질 값을 물리량에 묶어 두면 조명만 바꿔도 재질이 맞게 보입니다.
빛이 표면에서 갈리는 두 갈래
빛은 표면에 닿으면 두 갈래로 나뉩니다. 물리 기반 셰이딩의 계산은 결국 이 두 갈래의 몫을 나누는 일입니다.
빛의 일부는 표면 겉에서 곧장 튕겨 나갑니다. 이 몫이 정반사입니다. 광택 있는 표면에 맺히는 반짝임이 이 빛입니다.
나머지는 표면 안으로 들어갑니다. 안에서 여러 번 부딪히며 흩어지다가 일부가 사방으로 빠져나옵니다. 이 몫이 난반사입니다.
표면의 바탕색을 만드는 것이 이 빛입니다. 퐁 반사 모델이 무광 명암으로 따로 계산하던 것도 이 몫입니다.
안으로 들어간 빛이 어떻게 되는지는 재질이 금속인지로 갈립니다. 금속은 안으로 들어간 빛을 거의 다 삼킵니다. 그래서 금속에는 난반사가 거의 없습니다.
금속의 색은 겉에서 튕기는 빛에 묻어 나옵니다. 금의 반짝임이 노란 것도 이 때문입니다.
금속이 아닌 재질은 들어간 빛을 흩어서 내보냅니다. 플라스틱, 나무, 돌이 그렇습니다. 이런 재질의 바탕색은 난반사에서 옵니다. 겉에서 튕기는 반짝임은 색이 거의 없는 흰빛입니다.
flowchart TD
A["빛이 표면에 닿는다"] --> B["겉에서 곧장 튕긴다 · 정반사"]
A --> C["표면 안으로 들어간다"]
C --> D{"금속인가"}
D -->|예| E["거의 다 삼킨다"]
D -->|아니오| F["흩어져 사방으로 나온다 · 난반사"]
그림에서 갈래가 두 번 나뉩니다. 첫 갈림에서 겉으로 튕기는 몫은 보는 각도와 재질이 정합니다. 둘째 갈림은 재질이 금속인지 아닌지가 정합니다.
에너지 보존
두 갈래를 나누는 첫째 규칙은 표면이 내보내는 빛이 들어온 빛보다 많을 수 없다는 것입니다. 이 성질을 에너지 보존이라고 부릅니다. 빛도 에너지라서 표면이 없던 빛을 만들어 내지 못합니다.
이 규칙은 두 갈래를 서로 묶습니다. 겉에서 튕긴 몫이 크면 안으로 들어갈 빛이 그만큼 줄어듭니다. 그래서 반짝임이 센 표면일수록 바탕색이 어두워집니다.
퐁 반사 모델은 두 몫을 따로 정해 더했기 때문에 이 묶음이 없었습니다. 물리 기반 셰이딩은 한 몫을 먼저 정하고 남은 빛을 다른 몫에 넘깁니다. 어떤 값을 넣어도 표면이 빛을 지어내지 않습니다.
미세면과 거칠기
둘째 규칙은 표면의 거친 정도를 다룹니다. 매끈해 보이는 표면도 아주 가까이 보면 작은 면들이 이리저리 기울어 있습니다. 표면을 이런 작은 거울 조각의 모임으로 보는 방식이 미세면 모델입니다.
조각들이 고르게 한쪽을 향하면 빛이 한 방향으로 모여 튕깁니다. 그러면 반짝임이 작고 또렷하게 맺힙니다. 조각들이 제각각 기울어 있으면 빛이 여러 방향으로 퍼집니다. 그러면 반짝임이 넓고 흐릿해집니다.
조각들이 얼마나 제각각인지를 수 하나로 적은 값이 거칠기입니다. 0 이면 거울처럼 매끈하고, 1 에 가까울수록 거칩니다.
에너지 보존이 여기에도 걸립니다. 튕기는 빛의 총량은 두고 퍼지는 넓이만 바뀝니다. 그래서 반짝임이 넓어질수록 그 안의 한 점은 어두워집니다.
프레넬 반사
셋째 규칙은 보는 각도를 다룹니다. 표면을 비스듬히 볼수록 겉에서 튕기는 빛이 많아집니다. 이 현상을 프레넬 반사라고 부릅니다.
호수에서 쉽게 볼 수 있습니다. 발밑의 물을 내려다보면 바닥이 비쳐 보입니다. 멀리 있는 수면을 낮은 각도로 보면 하늘이 거울처럼 비칩니다.
표면을 정면에서 볼 때 겉에서 튕기는 비율을 정면 반사율이라고 부릅니다. 금속이 아닌 재질은 이 값이 몇 퍼센트 남짓으로 낮습니다. 재질끼리 차이도 작습니다.
금속은 이 값이 높고 빛의 색마다 다릅니다. 그래서 튕긴 빛에 금속의 색이 묻습니다.
어느 재질이든 표면과 거의 나란한 각도로 보면 반사율이 1 에 가까워집니다. 그래서 둥근 물체의 가장자리가 조금 더 밝게 빛납니다.
BRDF
지금까지의 규칙을 계산 하나로 묶은 것이 BRDF(Bidirectional Reflectance Distribution Function, 양방향 반사율 분포 함수)입니다. 빛이 들어온 방향과 눈이 보는 방향을 넣으면, 들어온 빛 가운데 눈 쪽으로 튕겨 나가는 비율을 돌려줍니다.
코드로 치면 재질 값을 설정으로 쥐고 두 방향을 인자로 받는 순수 함수입니다. 같은 인자를 넣으면 언제나 같은 비율이 나옵니다. 셰이딩은 광원마다 이 비율에 빛의 세기를 곱해 더합니다.
BRDF 는 앞의 두 갈래대로 반짝임 몫과 난반사 몫을 더한 꼴입니다. 반짝임 몫은 흔히 세 항을 곱해 만듭니다. 앞의 규칙들이 각각 한 항씩을 맡습니다.
법선은 표면이 향한 방향입니다. 미세면 조각마다 법선이 하나씩 있습니다. 표면이 거칠수록 조각들의 법선이 여러 방향으로 흩어집니다.
| 항 | 무엇을 계산하나 | 맡는 규칙 |
|---|---|---|
| 법선 분포 | 눈 쪽으로 빛을 튕기게 기운 조각이 얼마나 많은가 | 미세면과 거칠기 |
| 프레넬 | 이 각도에서 겉에서 튕기는 비율 | 프레넬 반사 |
| 기하 가림 | 조각끼리 서로 가려 막히는 빛의 몫 | 미세면과 거칠기 |
기하 가림은 거친 표면에서 생기는 손실입니다. 한 조각이 옆 조각의 그늘에 들어가거나, 튕긴 빛이 옆 조각에 막힙니다. 이 항이 그만큼 빛을 덜어 내어 거친 표면이 지나치게 밝아지지 않게 합니다.
세 항을 곱하는 이 꼴을 쿡-토런스 모델이라고 합니다. 처음 세운 두 사람의 이름을 땄습니다. 반짝임 몫은 대개 이 모델로 계산합니다.
난반사 몫은 보통 램버트 확산으로 계산합니다. 들어간 빛이 방향을 가리지 않고 사방으로 고르게 흩어진다고 보는 계산입니다. 그래서 어느 쪽에서 보아도 밝기가 같습니다.
계산이 도는 곳
이 계산은 화면의 점마다 한 번씩 돕니다. 점이 수백만 개라 이 계산을 맡는 장치가 따로 있습니다. 그 장치가 GPU(Graphics Processing Unit, 그래픽 처리 장치)입니다. 많은 점을 한꺼번에 계산하도록 만들어졌습니다.
GPU 에 끼워 넣어 돌리는 작은 프로그램이 셰이더입니다. 색을 어떤 계산으로 낼지를 만드는 사람이 이 프로그램에 적습니다.
그중 화면 점마다 한 번 돌아 색을 내는 셰이더가 프래그먼트 셰이더입니다. 물리 기반 셰이딩의 BRDF 계산은 대개 여기에 들어갑니다. 한 점을 비추는 광원이 여럿이면 광원마다 BRDF 를 불러 결과를 더합니다.
재질을 적는 값
만드는 사람은 재질을 몇 가지 값으로 적습니다. 가장 널리 쓰는 방식은 값 셋으로 적는 금속-거칠기 모델입니다.
| 값 | 범위 | 뜻 |
|---|---|---|
| 바탕색 | 색 하나 | 비금속이면 난반사의 색, 금속이면 반짝임의 색 |
| 금속성 | 0 또는 1 | 금속인지 아닌지 |
| 거칠기 | 0 ~ 1 | 미세면 조각이 얼마나 제각각 기울었나 |
바탕색은 알베도라고도 부릅니다. 여기에는 그늘이나 반짝임을 그려 넣지 않고 표면 고유의 색만 담습니다. 명암은 셰이딩이 계산하기 때문입니다.
금속성은 원칙적으로 0 이나 1 입니다. 표면은 금속이거나 아니거나 둘 중 하나이기 때문입니다. 사이 값은 녹슨 쇠의 경계처럼 두 재질이 섞인 곳에만 씁니다.
이 값들은 표면의 점마다 다를 수 있어서 그림 파일에 담아 둡니다. 표면에 입히는 이런 그림을 텍스처라고 부릅니다. 바탕색, 금속성, 거칠기 텍스처를 한 벌로 묶어 재질 하나를 만듭니다.
금속성 값 하나가 바꾸는 것
금속성 값이 앞의 두 갈래를 어떻게 바꾸는지 셰이더 코드 몇 줄로 봅니다. 먼저 금빛 금속입니다.
vec3 b = vec3(1.0, 0.8, 0.3); // 금빛
float m = 1.0; // 금속
vec3 f0 = mix(vec3(0.04), b, m); // 금빛
vec3 kd = b * (1.0 - m); // 0
b 는 바탕색, m 은 금속성, f0 은 정면 반사율, kd 는 난반사의 색입니다. mix(x, y, m) 은 m 이 0 이면 x 를, 1 이면 y 를 돌려줍니다.
0.04 는 비금속의 정면 반사율입니다. 앞에서 본 「몇 퍼센트 남짓」이 이 값입니다. 금속이 아닌 재질은 정면 반사율이 서로 비슷해서 흔히 이 값 하나로 대신합니다.
금속이라 정면 반사율이 바탕색인 금빛이 됩니다. 난반사는 0 이 됩니다.
이번에는 같은 코드에 빨간 플라스틱을 넣습니다.
vec3 b = vec3(0.8, 0.1, 0.1); // 빨강
float m = 0.0; // 비금속
vec3 f0 = mix(vec3(0.04), b, m); // 0.04
vec3 kd = b * (1.0 - m); // 빨강
비금속이라 정면 반사율은 색 없는 0.04 가 됩니다. 빨강은 난반사로 갑니다. 값 하나로 앞의 두 갈래가 통째로 뒤바뀌는 것을 볼 수 있습니다.
조명과 색 처리 쪽 준비물
재질만 물리에 맞춰서는 결과가 맞게 안 나옵니다. 계산에 넣는 빛도 실제 세기에 맞춰야 합니다. 들어오는 빛이 엉터리면 에너지 보존을 지켜도 결과가 엉터리입니다.
색 계산은 선형 색 공간에서 합니다. 수치를 두 배로 올리면 빛의 양도 두 배가 되는 색 공간입니다. 보통의 그림 파일은 사람 눈에 맞춰 값을 휘어서 저장하므로, 계산 전에 펴고 계산 뒤에 다시 휩니다.
현실의 밝기 차이는 화면이 낼 수 있는 범위보다 훨씬 넓습니다. 그래서 계산은 넓은 범위를 담는 HDR(High Dynamic Range, 높은 명암 범위)로 합니다. 한낮의 해와 그늘 속 바닥을 한 장면에서 함께 계산할 수 있습니다.
계산을 마친 값은 화면이 낼 수 있는 범위를 넘습니다. 이 값을 화면 범위로 줄이는 단계가 톤 매핑입니다. 밝은 곳이 하얗게 뭉개지지 않게 눌러 담습니다.
반들거리는 표면은 주변을 비춥니다. 광원 몇 개만 두면 금속 표면에 비칠 것이 없어 거의 까맣게 보입니다. 그래서 주변 풍경을 담은 사진을 빛으로 쓰는 이미지 기반 조명을 흔히 함께 씁니다.
쓰는 곳과 안 쓰는 곳
사실적인 모습이 여러 조명 아래에서 한결같아야 할 때 씁니다. 게임과 영화, 상품을 3차원으로 돌려 보는 화면이 그렇습니다.
도구끼리 재질을 주고받기 쉬워지는 것도 쓰는 이유입니다. 재질 값이 물리량이라 한 도구에서 만든 재질이 다른 도구에서도 같은 뜻을 갖습니다. 3차원 모형 파일 형식인 glTF(GL Transmission Format, GL 전송 형식)도 재질을 금속-거칠기 값으로 담습니다.
일부러 현실과 다르게 그리는 화면에는 맞지 않습니다. 만화처럼 면을 두세 단계 명암으로 끊어 칠하는 툰 셰이딩이 그런 예입니다. 물리에 맞추는 것이 목표가 아니므로 이 계산을 쓸 이유가 없습니다.
계산 여유가 아주 적은 기기에서는 옛 방식을 고르기도 합니다. 조명을 받지 않는 글자나 아이콘은 셰이딩 자체가 필요 없습니다.
대가
계산량이 늘어납니다. 퐁 반사 모델은 방향끼리 견주는 연산 몇 번이면 끝납니다. 쿡-토런스 모델은 세 항을 따로 계산해 곱합니다. 이 계산이 화면 점마다, 광원마다 돕니다.
미리 해 둘 계산도 생깁니다. 이미지 기반 조명은 주변 사진을 거칠기 단계별로 미리 흐려 둬야 합니다. 거친 표면에는 흐린 풍경이, 매끈한 표면에는 또렷한 풍경이 비쳐야 하기 때문입니다.
표현의 폭이 좁아집니다. 재질 값이 물리에 묶여 있어서, 현실에 없는 과장된 반짝임을 내려면 규칙을 일부러 어겨야 합니다.
이름은 물리 기반입니다. 그래도 물리를 빠짐없이 계산하지는 않습니다. 미세면 조각의 모양과 빛이 표면 안에서 흩어지는 길은 여전히 근사로 계산합니다. 목표는 정밀한 시뮬레이션이 아니라 조명이 바뀌어도 어긋나지 않는 그럴듯함입니다.
관련 항목
물리 기반 셰이딩을 이루는 반사 계산
BRDF · 미세면 모델 · 프레넬 반사 · 에너지 보존 · 쿡-토런스 모델 · 램버트 확산 · 난반사 · 정반사 · 법선 분포 함수
물리 기반 셰이딩이 재질을 적는 값
금속-거칠기 모델 · 스펙큘러-글로시니스 모델 · 알베도 · 거칠기 · 금속성 · 머티리얼 · 텍스처 · 노멀 매핑
물리 기반 셰이딩이 기대는 조명과 색 처리
선형 색 공간 · HDR · 톤 매핑 · 이미지 기반 조명 · 광원 · 감마 보정
물리 기반 셰이딩과 겨루는 셰이딩 방식
퐁 반사 모델 · 블린-퐁 반사 모델 · 툰 셰이딩 · 비사실적 렌더링
물리 기반 셰이딩을 싣는 GPU 단계
GPU · 셰이더 · 프래그먼트 셰이더 · 디퍼드 셰이딩 · G-버퍼
물리 기반 셰이딩이 다루지 않아 따로 계산하는 빛
전역 조명 · 광선추적 · 그림자 매핑 · 앰비언트 오클루전 · 표면하 산란
물리 기반 셰이딩 재질을 주고받는 파일 형식
glTF · USD · MaterialX · OpenPBR
물리 기반 셰이딩이 속하는 상위 분류
다른 이름: PBS · PBR · physically based shading · physically based rendering · 물리 기반 렌더링