수개월 전에 서브스트레이트 시그라프 2024 발표자료를 번역하고 공개한 적이 있죠?
최근 서브스트레이트 프레임워크 중심으로 여러가지 변경점, 개념, 시각적인 표현 모델 전반을 살펴보고 있습니다. 이미 2018년도에 구현되어 모더워페어 WW2 에 적용 된 여러가지 커스터마이징
2018년 콜옵듀티 개발 당시 개발 된 Diffuse Chan 에 대한 내용을 추가로 다루어보고자 한다.
이후 집필중인 책에 더 자세하게 담기겠지만...
셰이더 함수 Diffuse_Chan
은 Call of Duty: WWII에 사용된 재질 렌더링 기술의 일부로, 표면의 확산 반사광(diffuse reflection)을 계산하는 것이다. 이 셰이더는 현실적인 재질 표현을 목표로 다양한 요소를 고려하며, 특히 레트로 반사 효과를 줄여 시각적 품질을 높인다. 복잡한 조명 조건에서도 신뢰할 수 있는 시각적 표현을 제공하도록 설계되었다. 아래에서 이 코드를 단계별로 분석해보자.
함수 개요 및 주요 매개변수
BRDF.ush
- 함수명:
Diffuse_Chan
- 주요 매개변수:
DiffuseColor
: 표면의 기본 색상으로, 재질의 색상을 정의하고 조명이 닿았을 때의 색을 결정한다.a2
: 재질의 거칠기를 나타내는 변수로, 표면의 반사 특성과 관련 있다. 낮은 값은 매끄러운 표면을, 높은 값은 거친 표면을 나타낸다.NoV
,NoL
,VoH
,NoH
: 법선 벡터(Normal), 보기 벡터(View), 조명 벡터(Light) 간의 내적 값이다. 이 값들은 빛과 카메라 시점에 대한 벡터의 관계를 나타내며, 표면 반사의 세기를 결정하는 데 사용된다.RetroReflectivityWeight
: 레트로 반사 기여도를 조정하는 가중치로, 면광원 사용 시 시각적 아티팩트를 줄이기 위해 사용된다.
NoV = saturate(NoV);
NoL = saturate(NoL);
VoH = saturate(VoH);
NoH = saturate(NoH);
NoV
,NoL
,VoH
,NoH
값을 0에서 1 사이로 제한한다.
거칠기(g) 계산
float g = saturate((1.0 / 18.0) * log2(2 * rcpFast(a2) - 1));
g
는 재질의 거칠기와 관련된 값을 나타낸다. 이 값은 표면의 거칠기 정도에 따라 조명 반응을 조절하는 데 사용된다.rcpFast(a2)
는a2
의 역수를 빠르게 계산하기 위한 함수이다. 성능 최적화를 위해 사용되며, 이후log2
와 함께g
를 계산한다. 최종적으로g
는 0에서 1 사이로 제한되어 재질의 시각적 특성을 안정적으로 표현한다.- 거칠기 값은 표면의 빛 산란을 조정하는 중요한 역할을 한다. 표면이 매끄러울수록 빛은 특정 방향으로 더 많이 반사되고, 거칠수록 빛이 여러 방향으로 확산된다.
프레넬 반사 계산 (F0, FdV, FdL)
float F0 = VoH + Pow5(1 - VoH);
float FdV = 1 - 0.75 * Pow5(1 - NoV);
float FdL = 1 - 0.75 * Pow5(1 - NoL);
F0
,FdV
,FdL
은 각각 프레넬 반사를 계산한다. 프레넬 반사는 빛의 입사 각도에 따라 표면에서 반사되는 빛의 양이 달라지는 현상을 설명한다.F0
:VoH
와 Schlick 근사법(Pow5()
)을 사용하여 프레넬 반사량을 계산한다. 이 값은 특정 각도에서 빛이 얼마나 반사되는지를 결정한다.FdV
와FdL
: 보기 벡터(NoV
)와 조명 벡터(NoL
)의 내적을 기반으로 확산 반사를 계산한다. 이 값들은 빛이 관찰자와 표면 사이의 각도에 따라 얼마나 확산되는지를 나타낸다.Pow5(x)
는x
의 5제곱을 의미하며, 프레넬 반사 효과를 부드럽게 감소시키는 역할을 한다. 이 계산은 빛의 반사와 확산이 어떻게 일어나는지를 조절한다.
- 프레넬 반사는 물체의 표면에서 보는 각도에 따라 변화하는 반사 특성을 모델링하는 데 중요한 역할을 한다. 특히 빛이 낮은 각도로 입사할 때 더 많은 반사가 일어나는 것을 설명한다.
확산 조명 보간 (Fd)
float Fd = lerp(F0, FdV * FdL, saturate(2.2 * g - 0.5));
Fd
는F0
와FdV * FdL
을 보간(lerp
)하여 계산된다. 보간은 두 값을 특정 비율로 혼합하는 것으로, 여기서는g
값을 사용해 두 값 사이를 보간한다.g
값이 재질의 거칠기 정도를 나타내므로, 이를 통해 재질의 거칠기에 따른 확산 반사량을 조정한다. 매끄러운 표면은 빛을 더 특정한 방향으로 반사하고, 거친 표면은 빛을 더 넓게 확산시킨다.lerp
함수는 두 값을 선형적으로 보간하는 함수로,g
값에 따라F0
와FdV * FdL
사이의 적절한 값을 선택한다. 이로 인해 재질의 반사 특성이 부드럽게 변화하게 된다.
레트로 반사 기여도 계산 (Fb)
float Fb = ((34.5 * g - 59) * g + 24.5) * VoH * exp2(-max(73.2 * g - 21.2, 8.9) * sqrtFast(NoH));
Fb *= RetroReflectivityWeight;
Fb
는 레트로 반사 기여도를 계산한다. 레트로 반사는 빛이 입사한 방향으로 다시 반사되는 현상으로, 특정 각도에서 표면이 밝게 보이는 효과를 설명한다.- 이 식에서 여러 경험적 상수들이 사용된다. 이 상수들은 레트로 반사를 정교하게 모델링하기 위해 실험적으로 도출된 값들이다.
exp2()
와sqrtFast()
함수는 빠른 계산을 위해 사용된다. RetroReflectivityWeight
는 면광원(area light) 사용 시 레트로 반사가 줄어들도록 조정하여 시각적 아티팩트를 방지한다. 이 과정은 게임에서 자연스럽고 시각적으로 일관된 결과를 얻기 위해 중요하다.- 레트로 반사는 특히 운전 중 반사되는 도로 표지판 같은 상황에서 자주 볼 수 있는 현상인데, 이 특성을 제대로 모델링하면 현실감을 높일 수 있다.
최종 로브(Lobe) 계산 및 클램핑
float Lobe = (1 / PI) * (Fd + Fb);
Lobe = min(1.0, Lobe);
Lobe
는Fd
와Fb
를 더하여 최종적인 확산 반사 BRDF(Bidirectional Reflectance Distribution Function) 값을 계산한다. BRDF는 표면이 빛을 반사하는 방식과 관련된 수학적 모델이다.(1 / PI)
는 람베르트 확산 반사 모델의 정규화 계수로, 에너지 보존을 위해 사용된다. 람베르트 모델은 표면이 모든 방향으로 동일하게 빛을 반사한다고 가정하는 간단한 모델이다.- 최종적으로
Lobe
값을1.0
으로 제한(min
)하여 과도한 밝기 문제를 방지한다. 이 과정은 특히 노멀 맵을 사용할 때 가장자리에서 발생할 수 있는 과도한 밝기를 방지하고, 퍼니스 테스트에서 적절한 에너지 보존을 유지하기 위해 중요하다.- 퍼니스 테스트는 재질의 에너지 보존 특성을 확인하기 위해 사용되는 방법으로, 모든 방향에서 동일한 조명이 들어올 때 표면이 일관된 밝기를 유지해야 한다.
퍼니스 테스트(Furnace Test)는 3D 그래픽에서 재질의 에너지 보존 특성을 확인하는 데 사용하는 테스트 방법이다. 이 테스트는 모든 방향에서 동일한 강도로 조명이 들어오는 환경에서 물체의 표면이 어떻게 반응하는지를 관찰하여, 재질이 물리적으로 타당하게 구현되었는지 확인하는 데 도움을 준다.
퍼니스 테스트는 균일한 조명 조건에서 표면의 밝기나 반사가 일관되게 유지되는지 평가한다. 이는 재질의 에너지 보존을 확인하기 위한 중요한 과정으로서 에너지 보존은 입력된 에너지가 반사되거나 흡수되며, 출력 에너지가 입력 에너지를 넘지 않아야 한다는 물리 법칙을 의미한다. 만약 재질이 에너지 보존 특성을 따르지 않는다면, 반사되는 빛의 양이 지나치게 많아지거나 부족해져서 비현실적으로 보일 수 있다.
퍼니스 테스트의 목적은 이러한 에너지 보존을 위반하는 경우를 미리 찾아내어 수정하는 것이다.
재질이 모든 방향에서 동일한 조명을 받을 때 그 반응이 일관되고 물리적으로 타당해야 하므로, 이 과정은 3D 모델링 및 렌더링 작업에서 현실감을 높이는 데 중요한 역할을 한다.
관심이 있다면 아래 쓰레드를 읽어보자.
https://discussions.unity.com/t/unity-doesnt-pass-the-furnace-test/831316
최종 색상 계산 및 반환
return DiffuseColor * Lobe;
- 최종적으로 계산된
Lobe
값에DiffuseColor
를 곱하여 표면의 확산 반사 색상을 반환한다. 이 과정에서 조명과 재질의 특성을 반영하여 최종적으로 화면에 표시될 색상을 결정한다. DiffuseColor
는 표면의 고유 색상을 나타내고,Lobe
는 빛이 표면과 상호작용한 결과를 나타낸다. 두 값을 곱함으로써 현실적인 조명 효과를 적용한 최종 색상이 산출된다.- 이 최종 반환 값은 렌더링 파이프라인에서 화면에 그려지는 픽셀의 색상으로 사용된다. 이를 통해 게임에서의 사실적인 조명과 재질 표현이 가능하다.
이 셰이더 함수는 물리 기반 렌더링(PBR)을 통해 현실적인 확산 반사광을 구현한다.
PBR은 현실 세계의 물리적 특성을 기반으로 한 렌더링 기법으로, 재질의 물리적 특성을 정밀하게 시뮬레이션하여 더욱 사실적인 결과를 제공한다.
프레넬 반사, 레트로 반사, 쉐이딩 보간 등을 활용해 표면의 시각적 특성을 사실적으로 표현하고, 시각적 결함을 방지하기 위한 여러 보정 작업이 포함되어 있다. 특히 레트로 반사를 줄이기 위한 수정이 면광원 사용 시 적용되어 시각적 일관성을 유지한다.
복잡한 조명 상황에서도 안정적이고 현실적인 재질 표현이 가능하도록 설계된 이 함수는, 게임 그래픽에서 중요한 역할을 한다. 이러한 복잡한 재질 표현 기술을 통해 게임은 더욱 몰입감 있고 현실적인 시각적 경험을 제공할 수 있다.
다음 시간에는 최근 연구되고 있는 VMF Diffuse: A unified rough diffuse BRDF 에 대해서도 살짝 아루미 처럼 겉만 한번 훌터보겠습니다.
'UNREAL ENGINE' 카테고리의 다른 글
[번역] Using physical lighting units with Enlighten and UE4 (6) | 2024.11.06 |
---|---|
[소식] Z-emotion 언리얼엔진 업데이트. (1) | 2024.09.27 |
텐센트 PUER TypeScript 라이브러리 (0) | 2024.07.30 |
애러 추적 : GetSingleLayerWaterMaterialOutput 에 대해서... (0) | 2024.06.28 |
Individually Controllable Ambient Cubemap Color.UE5 (0) | 2024.02.15 |