셰이딩
고친 사람 github-actions[bot]
셰이딩은 물체 표면의 점마다 화면에 어떤 색으로 보일지 계산하는 일입니다. 빛을 받는 쪽은 밝게, 등진 쪽은 어둡게 칠합니다. 그 명암 덕분에 평평한 화면 속 물체가 입체로 보입니다. 자바 빌드에서 라이브러리의 패키지 이름을 바꿔 담는 의존성 셰이딩은 이름만 같은 다른 일입니다.
쉽고 빠른 이해
셰이딩은 표면의 점 하나가 무슨 색으로 보일지 계산하는 일입니다. 햇빛 아래 빨간 공이라면 해를 향한 쪽은 밝은 빨강으로, 반대쪽은 검붉은 색으로 칠합니다.
이 계산이 없으면 공의 모든 점이 같은 빨강이 됩니다. 그러면 공은 둥근 물체가 아니라 빨간 원판처럼 보입니다.
어떻게 도나:
- 그 점에서 표면이 어느 쪽을 향하는지 봅니다
- 빛이 어느 쪽에서 들어오는지 봅니다
- 둘이 마주 볼수록 밝게, 비껴갈수록 어둡게 표면 색을 조절합니다
대가는 계산량입니다. 점마다 따로 계산하므로 화면이 크고 빛이 많을수록 계산이 불어납니다. 그래서 얼마나 촘촘히 계산할지를 골라야 합니다.
상세
이 절은 셰이딩이 무엇을 받아 무엇을 내놓는지부터 봅니다. 그다음 가장 단순한 명암 계산 하나를 숫자로 따라갑니다. 이어서 그 계산을 얼마나 촘촘히 하느냐로 갈리는 방식들을 견줍니다. 끝으로 비용이 어디에 붙는지를 봅니다.
어두운 방에서 손전등으로 벽을 비춰 봅니다. 정면으로 비추면 작고 밝은 동그라미가 맺힙니다. 손전등을 비스듬히 기울이면 같은 빛이 넓게 퍼져 흐려집니다.
셰이딩은 이 밝기 차이를 숫자로 계산하는 일입니다. 빛이 표면에 곧게 닿는 점은 밝게, 비스듬히 닿는 점은 어둡게 칠합니다.
이 계산이 없으면 표면의 모든 점이 같은 색으로 칠해집니다. 빨간 공은 둥근 물체가 아니라 빨간 원판처럼 보입니다. 화면은 평평하므로 입체감은 점마다 다른 명암에서만 나옵니다.
3차원 장면을 화면 한 장으로 옮기는 일 전체가 렌더링입니다. 렌더링은 물체가 화면의 어디에 놓일지를 먼저 정합니다. 셰이딩은 그 뒤에 놓인 점 하나하나의 색을 정합니다.
셰이딩이 받는 세 가지 값
셰이딩은 표면 위 점 하나를 두고 한 번 돕니다. 내놓는 것은 그 점의 색 하나입니다. 그 색을 계산하려면 세 가지를 알아야 합니다.
첫째는 표면이 향한 방향입니다. 이 방향을 법선이라고 부릅니다. 그 점에서 표면에 수직으로 세운 화살표입니다. 공이라면 꼭대기의 법선은 곧장 위를, 옆구리의 법선은 옆을 가리킵니다.
둘째는 빛입니다. 빛을 내는 물체를 광원이라고 부릅니다. 셰이딩은 광원이 어느 쪽에 있는지와 무슨 색으로 얼마나 세게 비추는지를 읽습니다.
셋째는 표면 자체의 성질입니다. 표면의 바탕색과 반들거리는 정도를 묶어 재질이라고 부릅니다. 같은 빛을 받아도 무광 플라스틱과 광택 있는 플라스틱은 다르게 보입니다.
| 받는 값 | 무엇인가 | 예 |
|---|---|---|
| 법선 | 그 점에서 표면이 향한 방향 | 공 꼭대기에서는 곧장 위 |
| 빛 | 광원의 방향 · 색 · 세기 | 오른쪽 위에서 오는 흰 햇빛 |
| 재질 | 표면의 바탕색과 반들거림 | 무광 빨강 · 광택 있는 빨강 |
방향은 x · y · z 세 수로 적는 화살표, 곧 벡터로 다룹니다. 길이는 1로 맞춰 방향만 남겨 씁니다.
그림에서 읽어 오는 법선
세 값 가운데 법선은 그림 파일에서 읽어 오기도 합니다. 이 소절은 그 방법과, 그때 법선 말고 더 필요한 방향 하나를 봅니다.
표면에 입히는 그림을 텍스처라고 부릅니다. 벽돌 벽 사진을 평평한 사각형에 입히면 벽돌 무늬가 보입니다. 텍스처에는 색 말고 다른 값도 담을 수 있습니다.
법선을 텍스처에 담아 두는 기법이 노멀 매핑입니다. 점마다 조금씩 다른 법선을 읽어 오면 평평한 면에도 벽돌 틈 같은 굴곡의 명암이 생깁니다. 삼각형을 늘리지 않고 명암만으로 굴곡을 냅니다.
텍스처에 적힌 법선은 평평하게 펼친 면을 기준으로 한 방향입니다. 실제 표면은 휘거나 돌아가 있습니다. 그래서 그 방향을 표면에 맞게 돌려서 씁니다.
돌리려면 법선 말고도 표면 위의 가로 방향과 세로 방향을 알아야 합니다. 법선만으로는 표면이 제자리에서 얼마나 돌았는지 알 수 없기 때문입니다. 그 가운데 표면을 따라 눕는 가로 방향이 탄젠트입니다.
표면이 빛을 마주 보는 정도
이 소절은 가장 흔한 명암 계산 하나를 값으로 따라갑니다. 계산에 쓰는 연산은 하나뿐입니다.
두 방향이 얼마나 같은 쪽을 향하는지를 수 하나로 주는 연산이 내적입니다. 길이가 1인 두 화살표라면 같은 쪽일 때 1, 직각일 때 0, 정반대일 때 -1 이 나옵니다.
가장 단순한 셰이딩은 법선과 빛 쪽 방향의 내적을 밝기로 씁니다. 빛 쪽 방향은 그 점에서 광원을 바라보는 화살표입니다. 이렇게 계산한 명암이 난반사입니다. 거친 표면이 빛을 사방으로 고르게 흩뜨리는 모습을 흉내 낸 계산입니다.
아래 코드는 이 계산을 점 하나에 대해 적은 것입니다. 빨간 표면 위 한 점에 빛이 비스듬히 들어오는 경우입니다.
vec3 n = vec3(0.0, 1.0, 0.0); // 곧장 위
vec3 l = vec3(0.0, 0.6, 0.8); // 비스듬히
vec3 b = vec3(1.0, 0.0, 0.0); // 빨강
float d = max(dot(n,l), 0.0); // 0.6
vec3 c = b * d; // (0.6, 0, 0)
n 은 법선, l 은 빛 쪽 방향, b 는 재질의 바탕색입니다. 두 방향의 내적은 0×0 + 1×0.6 + 0×0.8 이라 0.6 입니다. 그래서 이 점은 빨강에 0.6 을 곱한 어두운 빨강으로 칠해집니다.
빛이 머리 위에서 곧장 내리쬐면 내적이 1 입니다. 바탕색에 1 을 곱하니 색이 바뀌지 않습니다. 빛이 옆으로 누울수록 값은 0 에 가까워집니다. 앞의 손전등을 기울일수록 흐려지던 것이 이 값입니다.
빛이 표면 뒤쪽에서 오면 내적이 음수가 됩니다. 음수 밝기는 뜻이 없으므로 max 로 0 에 묶습니다. 빛을 등진 쪽이 까맣게 되는 까닭이 이것입니다.
반짝임과 바탕 밝기
난반사만으로 칠하면 분필이나 종이 같은 무광 표면이 됩니다. 반들거리는 표면과 그늘진 쪽을 내려면 계산 두 가지를 더 얹습니다.
반들거리는 표면에는 빛이 한 점에 몰려 반짝이는 부분이 생깁니다. 이 반짝임을 정반사라고 부릅니다. 빛이 거울처럼 튕겨 나간 방향이 보는 눈 쪽과 겹칠수록 밝아집니다. 그래서 보는 위치를 옮기면 반짝임도 따라 움직입니다.
빛을 등진 쪽도 현실에서는 완전히 까맣지 않습니다. 벽과 바닥에서 튕긴 빛이 사방에서 조금씩 들어오기 때문입니다. 이것을 일일이 계산하는 대신 모든 점에 같은 밝기를 조금 얹습니다. 이 바탕 밝기가 주변광입니다.
세 성분이 무엇을 보는지는 이렇게 갈립니다.
| 성분 | 무엇을 보나 | 눈을 옮기면 |
|---|---|---|
| 주변광 | 아무것도 안 본다. 모든 점에 같은 값 | 안 바뀐다 |
| 난반사 | 법선과 빛 쪽 방향 | 안 바뀐다 |
| 정반사 | 튕긴 빛의 방향과 눈 쪽 방향 | 바뀐다 |
셋을 더한 값이 그 점의 색이 됩니다. 이 세 성분을 더해 명암을 내는 계산이 퐁 반사 모델입니다.
이 합은 빛의 물리를 그럴듯하게 흉내 낸 어림셈입니다. 빛이 표면에서 얼마나 튕기는지를 물리 법칙에 맞춰 계산하는 방식은 물리 기반 셰이딩이 따로 다룹니다.
계산하는 단위 세 가지
같은 계산을 몇 번 하느냐에 따라 결과가 달라집니다. 이 소절은 계산하는 단위 세 가지를 견줍니다. 그다음 그 계산이 그림 그리는 흐름의 어느 단계에 들어가는지 봅니다.
물체 겉면은 보통 작은 삼각형을 이어 붙인 모형으로 그립니다. 이 모형이 메시입니다. 삼각형의 꼭짓점 하나하나는 정점입니다.
꼭짓점에만 있는 값으로 삼각형 안쪽을 채우려면 값을 섞어야 합니다. 안쪽의 점이 세 꼭짓점에서 얼마나 떨어졌는지를 보고 그 비율대로 섞습니다. 이 계산을 보간이라고 부릅니다.
| 방식 | 계산하는 단위 | 보이는 모습 |
|---|---|---|
| 플랫 셰이딩 | 삼각형 하나마다 한 번 | 면마다 색이 하나라 각이 드러난다 |
| 정점 단위 조명 | 꼭짓점마다 한 번, 안쪽은 보간 | 매끈하지만 반짝임이 뭉개지거나 사라진다 |
| 픽셀 단위 조명 | 화면 점마다 한 번 | 반짝임이 또렷하다. 계산이 가장 많다 |
정점 단위 조명은 구로 셰이딩, 픽셀 단위 조명은 퐁 셰이딩이라는 이름으로도 부릅니다. 퐁 셰이딩은 앞의 퐁 반사 모델과 이름이 겹칩니다. 반사 모델은 색을 내는 계산식입니다. 퐁 셰이딩은 그 계산을 화면 점마다 하는 방식입니다.
정점 단위 조명에서 반짝임이 사라지는 까닭은 계산하는 곳이 꼭짓점뿐이기 때문입니다. 반짝이는 점이 큰 삼각형 한가운데 떨어지면 세 꼭짓점 어디에서도 밝게 나오지 않습니다. 섞을 값에 밝은 값이 없으니 가운데도 밝아지지 않습니다.
GPU(Graphics Processing Unit, 그래픽 처리 장치)는 그림을 그리는 계산을 맡는 장치입니다. GPU 가 그림을 그리는 흐름은 단계가 정해져 있습니다.
그 흐름에는 만드는 쪽이 직접 프로그램을 적어 끼워 넣는 칸이 있습니다. 그 칸에 들어가는 작은 프로그램이 셰이더입니다. 덕분에 색을 내는 계산을 만드는 쪽이 바꿔 쓸 수 있습니다.
셰이딩에 쓰이는 칸은 주로 둘입니다. 그림은 꼭짓점 놓기 → 덮인 화면 점 고르기 → 점마다 색 내기 순서로 그려집니다. 첫째와 셋째 단계가 그 두 칸입니다.
정점 셰이더는 꼭짓점마다 한 번 돕니다. 그 꼭짓점을 화면 어디에 둘지 정합니다.
그다음 래스터화가 삼각형이 덮는 화면 점을 골라냅니다. 프래그먼트 셰이더는 그렇게 덮인 점마다 한 번 돌아 색을 냅니다.
정점 단위 조명과 픽셀 단위 조명은 계산을 두 칸 중 어디에 두느냐로 갈립니다.
flowchart TD
subgraph A["정점 단위 조명"]
A1["정점 셰이더 · 색을 계산한다"] --> A2["래스터화 · 색을 보간한다"]
A2 --> A3["프래그먼트 셰이더 · 보간된 색을 쓴다"]
end
subgraph B["픽셀 단위 조명"]
B1["정점 셰이더 · 법선을 넘긴다"] --> B2["래스터화 · 법선을 보간한다"]
B2 --> B3["프래그먼트 셰이더 · 색을 계산한다"]
end
A ~~~ B
보간하는 대상이 색이냐 법선이냐가 차이의 전부입니다. 법선을 보간해 넘기면 삼각형 한가운데 점도 자기 몫의 법선을 받습니다. 그래서 거기 떨어진 반짝임도 제대로 계산됩니다.
셰이딩과 셰이더
셰이더라는 이름은 셰이딩에서 왔습니다. 처음에는 표면의 명암을 계산하는 프로그램이라는 뜻이었습니다.
지금은 이름과 하는 일이 벌어졌습니다. 정점 셰이더는 색이 아니라 꼭짓점 위치를 옮깁니다. 컴퓨트 셰이더는 그림과 상관없는 계산에도 쓰입니다. 셰이더는 GPU 에 끼워 넣는 프로그램입니다. 셰이딩은 그 프로그램이 흔히 맡는 계산 하나입니다.
셰이딩이 보지 않는 것
지금까지의 계산은 점 하나와 광원, 보는 눈만 봅니다. 그 사이에 다른 물체가 끼어 있는지는 보지 않습니다. 그래서 공 뒤에 있는 바닥도 광원을 향하고 있으면 밝게 칠해집니다.
그림자를 내려면 광원에서 그 점이 보이는지를 따로 계산해야 합니다. 흔한 방법이 그림자 매핑입니다.
다른 물체에서 튕겨 온 빛까지 계산하는 일은 전역 조명이라고 부릅니다. 앞의 주변광은 이 계산을 상수 하나로 갈음한 것입니다.
빛이 지나는 길을 하나하나 따라가는 광선추적이 전역 조명을 계산하는 방법의 하나입니다.
비용이 붙는 곳
셰이딩은 점마다 따로 돕니다. 가로 1920, 세로 1080 화면이면 점이 이백만 개가 넘습니다. 1초에 60장을 그리면 점 하나짜리 계산이 1초에 1억 번 넘게 돕니다.
빛이 여럿이면 그 수만큼 곱해집니다. 광원 하나마다 난반사와 정반사를 따로 계산해 더하기 때문입니다. 그래서 광원을 늘리면 계산이 화면 점 수와 광원 수의 곱으로 불어납니다.
가려져 안 보일 점까지 계산하는 낭비도 있습니다. 여러 물체가 같은 화면 점을 덮어도 끝내 남는 것은 맨 앞 하나입니다. 그래도 덮은 물체마다 계산이 돕니다.
이 낭비를 줄이는 방식이 디퍼드 셰이딩입니다. 법선과 재질 같은 표면 정보만 먼저 모아 둡니다. 끝까지 남은 점에만 셰이딩을 한 번 합니다.
관련 항목
셰이딩이 받는 입력
법선 · 광원 · 머티리얼 · 텍스처 · 노멀 매핑 · 탄젠트
셰이딩을 이루는 반사 성분
난반사 · 정반사 · 주변광 · 퐁 반사 모델 · 블린-퐁 반사 모델 · 조명
셰이딩을 계산하는 단위별 방식
플랫 셰이딩 · 정점 단위 조명 · 픽셀 단위 조명 · 보간
셰이딩이 칠하는 기하 모형
셰이딩 계산을 싣는 GPU 단계
GPU · 셰이더 · 정점 셰이더 · 래스터화 · 프래그먼트 셰이더 · 컴퓨트 셰이더 · 렌더 파이프라인
셰이딩이 쓰는 벡터 연산
벡터 · 내적 · 정규화 · 반사 벡터
셰이딩이 맡지 않아 따로 계산하는 빛
그림자 매핑 · 전역 조명 · 광선추적 · 앰비언트 오클루전
셰이딩 비용을 줄이는 렌더링 방식
디퍼드 셰이딩 · 포워드 렌더링 · 포워드 플러스 렌더링 · 클러스터드 셰이딩 · G-버퍼 · 오버드로
셰이딩을 물리 법칙에 맞춘 모델
물리 기반 셰이딩 · BRDF · 미세면 모델 · 프레넬 반사
셰이딩이 속하는 상위 분류
그래픽스 · 렌더링 · 실시간 렌더링 · 3D 그래픽스
셰이딩과 이름이 겹치는 빌드 기법
의존성 셰이딩 · 패키지 재배치 · 팻 JAR
다른 이름: shading · 음영 처리