MOONSUN
[그래픽스] PBR 이론 및 구현 : BSDF, BRDF, Cook–Torrance 본문
앞 글에서 PBR이해를 위한 기초 개념들을 알아보았는데
이어서 PBR(Physically Based Rendering)을 이해하려면,
빛이 표면에서 어떻게 반사·투과·산란되는지를 수학적으로 모델링한 BSDF 개념을 알아야 한다.
1. BSDF(빛-표면 시뮬레이션 모델)란?
BSDF(Bidirectional Scattering Distribution Function) : 양방향 산란 분포함수 라고 하며,
빛이 표면에 들어왔을 때, 표면 특성에 따라서 반사(Reflection), 산란(Scattering), 투과(Transmission) 등이 어떻게 일어나는지를 설명하는 가장 큰 개념
다음 4가지 모델을 포함한다:
- BRDF (Bidirectional Reflectance Distribution Function) : 양방향 반사율 분포 함수
- 불투명 표면에서 사용
- 빛이 한 지점에 입사했을 때, 같은 지점에서 반사되는 빛의 양과 방향을 계산
- 투과는 없고, 반사 + 산란(diffuse)만 고려
- ex : 벽, 돌, 나무, 금속, 거울
- BTDF (양방향 투과 분포 함수)
- 투명하거나 반투명한 표면에서 사용
- 빛이 한 지점에 입사했을 때, 특정 방향으로 통과되는 빛의 양과 방향 계산
- 표면 반사가 아니라, 빛의 투과/굴절 을 다룸
- ex : 유리, 투명 플라스틱
- BSSRDF (양방향 표면 산란 반사 분포 함수)
- BRDF + BTDF 확장판
- 투명하거나 반투명한 재질에서 + 내부 산란(SSS : Subsurface Scattering)을 표현할 때 사용
- 빛이 표면에 들어온 지점과 다른 지점에서 나오는 빛까지 고려하는 모델
- ex : 피부, 대리석, 우유
- BxDF
- 위 개념들을 모두 묶어 부르는 경우
PBR 게임 엔진에서는 보통 BRDF만 구현
(대부분의 게임은 불투명 재질 중심 / SSS는 별도 구현)
1-1. BRDF의 산란(Diffuse Reflection) vs BSSRDF의 산란(Subsurface Scattering)
이전 글에서도 언급했었지만 Diffuse와 Subsurface Scattering(SSS) 은 다른 것이다.
BRDF의 산란 (Diffuse Reflection)
- 빛이 표면에 닿자마자 바로 나가는 것.
- ex : 흰 벽에 빛을 비추면, 벽 표면에서 빛이 바로 튀어나오면서 주변을 밝힌다.
- 빛이 표면 안쪽으로 깊게 들어가지 않는 특징.
- "표면 위에서 튀어나오는 빛"
BSSRDF의 산란 (Subsurface Scattering)
- 빛이 표면 안으로 스며들어, 내부를 통과한 뒤 다른 위치에서 나오는 것.
- ex : 피부에 빛을 비추면, 빛이 피부 속을 살짝 통과해서 주름이나 피부 전체에서 부드럽게 퍼지는 느낌
- 빛이 표면 내부로 들어가는 특징.
- 입사한 위치와 다른 위치에서 빛이 나옴.
- "표면 속으로 들어가 굴러 나온 빛"
BRDF diffuse → 표면 위에서 바로 퍼지는 빛
BSSRDF SSS → 표면 안으로 들어가 다른 위치에서 퍼지는 빛
2. BSDF가 지켜야 하는 3가지 물리 법칙
2-1. 에너지 보존(Energy Conservation)
나가는 빛 에너지는 절대 들어온 빛보다 많을 수 없음.
들어온 빛 = 반사 + 흡수(열) + 투과 + 산란 ≥ 나가는빛의 양
즉, 반사, 흡수,투과,산란 과정을 통하여 분산 될 뿐이다.
항상 kD + kS = 1
2-2. 상호성(Reciprocity)
조명 방향과 시선 방향을 바꿔도 결과가 같아야 한다.
( 빛의 들어오는 방향 , 나가는 방향을 바꾸어도 결과가 동일한 결과를 제공해야 함을 의미 )
2-3. 물리적 타당성(Physical Plausibility)
표면의 실제 거칠기·재질·반사 특성에 맞는 모델링이 되어야 한다.
대부분 미세면 모델(Microfacet Model)을 사용해서 이를 만족한다.
(참고) Blinn-Phong은 1번·3번을 지키지 못함 → 그래서 비물리적이었음
현대 PBR은 모두 미세면 BRDF 사용
3. BRDF란?
불투명 표면에서, 한 지점에 들어온 빛이 같은 지점에서 반사 + 산란(diffuse) 되는 양을 계산하는 함수
Bidirectional 양방향, Reflectance 반사, Distrubution 분포, Function 함수

빛은 두가지 성분으로 나뉜다:
- 정반사(Specular) → 반짝이는 하이라이트
- 난반사(Diffuse) → 부드러운 전체 표면색
그리고 항상 kD + kS = 1 (에너지 보존)
kD : 정반사 비율(Specular term)
kS : 난반사 비율(Diffuse term)
4. 미세면 모델(Microfacet Model)
표면은 매끄러워 보이지만, 실제로 작은 미세면들로 이루어져 있다.
하나의 프래그먼트를 이렇게 여러 미세면으로 보는 것이 Microfacet 모델
각 미세면은 자기만의 법선(Normal)을 가지고 있고, 빛이 반사될 때 이 미세면의 법선 방향에 따라 반사 방향이 달라짐
결과적으로 하이라이트가 퍼지거나 거칠게 보이는 현상을 설명할 수 있음
Microfacet의 핵심 파라미터
| 파라미터 | 의미 | 효과 |
| Roughness | 거칠기 | 작으면 하이라이트가 좁고 날카롭고, 크면 넓고 흐림 |
| Metalness | 금속성 | 0: 비금속 → 반사 색이 고정(0.04) 1: 금속 → BaseColor를 반사 |
| Shadowing & Masking | 미세면 가림 | 각도에 따라 일부 미세면이 빛/시야에서 가려짐 |
5. Cook-Torrance BRDF
현대 PBR 엔진 (언리얼·유니티 URP/HDRP·Disney BRDF 등) 에서 가장 널리 쓰이는 정반사(Specular) 모델로, 미세면 모델(Microfacet model)을 기반으로 한다.
// 전체 반사율 계산 식
Specular BRDF = (D * F * G) / (4 * N·L * N·V)

여기서 핵심 구성은 세 가지:
| 요소 | 이름 | 역할 | 특징 |
| D(h) | Normal Distribution Function | 법선 분포 | 하이라이트 크기와 강도 결정 |
| F(v,h) | Fresnel | 프레넬 현상 적용 | 입사각·금속성에 따른 반사율 |
| G(l,v,h) | Geometry / Shadow-Masking | 기하학적 감쇠 | 미세면 가림/그늘짐 |
Half vector(h) 는 반사벡터 계산량을 줄이기 위해 N과 H를 사용한다.
각 함수는 물리 함수의 근사식이며, 다양한 방식으로 이론을 근사화 하는 함수가 있을 수 있다.
6. D, F, G 상세 정리
Cook-Torrance Specular BRDF는 미세면(Microfacet) 모델 기반으로 Specular를 계산할 때, D, F, G 세 가지 요소를 곱해서 최종 반사율을 구한다.
6-1. D(h) : 법선 분포 함수 (Normal Distribution Function, NDF)
표면의 미세한 돌기(미세면, microfacet)가 어떻게 배치되어 있는지 나타낸다.
즉, 표면의 거칠기 (Roughness) 를 통계적으로 표현한 함수.
- 빛이 들어올 때, 각 미세면이 반사에 기여할 수 있는 비율을 결정하고
- 하이라이트가 날카롭게 보일지, 퍼지게 보일지를 정함
| 거칠기(α)가 낮음 | → 미세면이 거의 정렬 | → 하이라이트 날카로움 |
| 거칠기(α)가 높음 | → 미세면이 불규칙 | → 하이라이트 퍼짐 |
6-2. F(v,h) : 프레넬 반사 (Fresnel reflection)
(앞 글에서 정리했던 프레넬 현상을 BRDF에 적용한 함수.)
빛이 표면에 입사할 때 반사되는 비율을 계산한다.
입사각과 재질의 금속성(Metalness)에 따라 변화
- 표면에서 입사각이 커질수록 반사가 강해지는 현상을 자연스럽게 구현
- 금속/비금속에 따라 반사율이 달라짐
“빛이 표면을 비스듬히 바라볼수록 더 많이 반사된다”
| v-h 사이각이 작으면 | → F0 기준 반사율 |
| v-h 사이각이 커지면 | → 반사율 증가 (글로우/하이라이트 강조) |
| F0 = | 금속성, 비금속 기본 반사율 + 텍스처 색상 |
6-3. G(l,v,h) : Geometry/Shadowing (Geometric Attenuation Function)
미세면 일부가 가려지거나, 그림자 때문에 반사되지 못하는 부분을 고려한다.
시야 방향(V), 빛 방향(L), 법선 방향(N), 거칠기(α)에 따라 결정.
- 현실에서는 모든 미세면이 항상 빛을 반사하지 않음
- 일부 미세면은 다른 미세면에 가려지거나, 입사 빛을 받지 못함 → 반사 감소
“빛이나 시야 때문에 반사되지 못하는 미세면을 계산해주는 함수”
| 거칠기가 클수록 | → 일부 미세면 가려짐 ↑ | → 전체 반사율 감소 |
| n-v, n-l 각도가 클수록 | → 가려지는 효과 ↑ |
7. BRDF 계산 구조 정리
앞에서 계속 알아보았던 것을 최종적으로 정리하면 다음과 같다.
BRDF = Specular + Diffuse
1-1. Specular: 반짝이는 하이라이트, 표면 금속성/입사각/시야각 고려

- 계산 방법: Cook-Torrance 미세면 모델 사용
- D(h): 법선 분포 함수 → 미세면 거칠기(Roughness)
- F(v,h): 프레넬 반사 → 금속성(Metalness) + 입사각 고려
- G(l,v,h): 기하학적 감쇠 → 미세면 일부가 가려지거나 반사되지 않는 효과
1-2. Diffuse: 표면 전체 색, 부드러운 난반사, 모든 방향으로 균일하게 퍼지는 빛

- 계산 방법: Lambertian Diffuse
- kD * BaseColor / π
1-3. 최종 빛 계산

여기에 입사각 N·L (Lambert 코사인 법칙) 곱하면 실제 표면에서 받는 빛의 양 반영
즉, BRDF는 Specular(Cook-Torrance) + Diffuse(Lambertian) 합으로 계산하며,
Specular에서는 미세면 모델(D,F,G)을 사용하고, Diffuse는 단순 난반사로 처리한다.
8. 최종 조명 공식 (정리)
하나의 빛에 해당되는 식은 아래와 같다.
( SpecularBRDF결과 + DiffuseBRDF결과) * 빛의 강도(Radiance) * NdotL
Final = (DiffuseBRDF + SpecularBRDF) * LightRadiance * max(N·L, 0)
8-1. Specular(정반사) 성분 계산 : Microfacet 기반 Cook-Torrance 모델
Cook-Torrance Specular BRDF는 다음 세 요소로 구성된다.

| 항목 | 의미 |
| D(h) | Normal Distribution Function → 얼마나 많은 미세면이 반사 조건(h)과 맞는지 |
| F(v,h) | Fresnel 현상 → 시야각에 따라 반사되는 비율 |
| G(l,v,h) | Geometry Shadowing → 자기 그림자/마스킹으로 감소하는 부분 |
Specular 색과 강도는 Fresnel(F)이 가장 큰 역할을 한다
8-2. Diffuse(난반사) 성분 계산

Diffuse는 무광 재질에서 모든 방향으로 균일하게 퍼지는 빛.
여기서 kD(표면 산란 비율)이 매우 중요
8-3. kS / kD (반사율–표면산란율) 분리
입사한 에너지 100% = 반사되는 부분(kS) + 산란되는 부분(kD)

하지만 금속 Workflow (Metalness Workflow) 에서는 다음 규칙이 추가된다:
- 비금속(Dielectric) → 반사색은 회색(F0 ≈ 0.04), Diffuse 존재
- 금속(Metal) → 반사색=BaseColor, Diffuse 없음(kD=0)
그래서 shader에서는 lerp() 로 처리한다:

kD = lerp(1 - F, 0, metalness)
| metalness=0 | kD = 1 - F | 일반 물체 |
| metalness=1 | kD = 0 | 금속 재질 |
8-4. F0 계산 (금속성에 따른 기본 반사율)
금속 Workflow에서 가장 중요한 초기값:
float3 F0 = lerp(Fdielectric, baseColor, metalness);
- 비금속 → F0 = Fdielectric (일반적으로 RGB 0.04)
- 금속 → F0 = BaseColor (금속의 고유 반사색)
8-5. Fresnel Schlick 근사식으로 실제 반사율(F) 계산
빛의 방향과 시선 방향의 반각(Lh, Lo)을 사용해
현재 상황에서의 반사율(F)을 계산한다:
float3 F = fresnelSchlick(F0, max(0.0, dot(Lh, Lo)));
→ 시선이 스칠수록( grazing ) 반사가 강해진다.
- Lh : H와 L의 내적(dot(H, L))
- Lo : H와 V의 내적(dot(H, V))
| 코드 표현 | 진짜 의미 |
| Lh | dot(L, H) = 빛 방향과 반각 벡터의 각도 |
| Lo | dot(V, H) = 시선 방향과 반각 벡터의 각도 |
8-6. Cook-Torrance D, G 계산
float D = ndfGGX(cosLh, max(0.1, roughness)); // 법선 분포 함수
float G = gaSchlickGGX(cosLi, cosLo, roughness); // 기하학적 감쇠
GGX는 사실감을 높이는 현대 PBR의 표준 NDF/Geometry 모델.
8-7. Diffuse / Specular BRDF 계산
float3 diffuseBRDF = kd * baseColor / PI;
float3 specularBRDF = (F * D * G) / max(Epsilon, 4.0 * cosLi * cosLo);
8-8. 정리 요약
BRDF는 Diffuse(산란) + Specular(반사)로 계산되며,
Specular는 Cook-Torrance(D·F·G)로 계산하고,
Diffuse는 kD*BaseColor/π로 계산한 뒤,
금속성(metalness)으로 F0, kS, kD를 조절하여
최종 빛의 에너지 보존을 만족하는 PBR 조명을 만든다.
9. 전체 코드
// 1. 금속성 기반 기본 반사율(F0) 결정
float3 F0 = lerp(Fdielectric, baseColor, metalness);
// 2. Fresnel Schlick으로 시선각 기반 반사율 계산
float3 F = fresnelSchlick(F0, max(0.0, dot(Lh, Lo)));
// 3. GGX 기반 D, G 계산
float D = ndfGGX(cosLh, max(0.1, roughness));
float G = gaSchlickGGX(cosLi, cosLo, roughness);
// 4. 금속성 반영한 Diffuse 비율 결정
float3 kd = lerp(1 - F, float3(0,0,0), metalness);
// 5. BRDF
float3 diffuseBRDF = kd * baseColor / PI;
float3 specularBRDF = (F * D * G) / max(Epsilon, 4.0 * cosLi * cosLo);
// 6. 최종 광원 기여
float3 final =
(diffuseBRDF + specularBRDF) * lightRadiance * max(dot(N, L), 0);
'D3D' 카테고리의 다른 글
| [그래픽스] IBL (Image Based Lighting) : PBR을 위한 환경 기반 간접광 (0) | 2025.12.10 |
|---|---|
| [그래픽스] PBR(PBR Rendering)에서의 감마 보정 (0) | 2025.12.03 |
| [그래픽스] PBR(Physically Based Rendering) : 빛의 물리 기반 렌더링의 이해 (0) | 2025.12.01 |
| [그래픽스] Toon Shading의 OutLine 표현 : 실루엣 Pass (0) | 2025.11.11 |
| [그래픽스] Toon Shading (툰 셰이딩) : Lambert 단계화 & Ramp Texture 방식 (0) | 2025.11.10 |