본문 바로가기

카테고리 없음

언리얼 루멘 공부 Lumen

<Lumen>

- 만약 루멘으로 할거면 프로젝트 세팅을 제대로 해줘야 함. 그래서 프로젝트 세팅에서는 어떤걸 해줘야 하는지는 Static vs Dynamic Lighting 영상 참고 (Ray Lighting Mode : hit lighting mode(?) / Software Raytracing Mode : Detail Tracing / Generate Mesh Distance Field Check(중요!) / RHI : DirectX 12 / Virtual Texture Support Check)
- 루멘 세팅법 : 프로젝트 세팅 > Dynamic Global Illumination을 Lumen으로 바꾸면 다른 것도 자동으로 바뀌긴 한데 몇 개 보자면 Reflection MethodLumen / Generate Mesh Distance Field 체크
- 모든 맵에서 일관된 라이팅 세팅을 하려면 프로젝트 세팅에서 세부 조정을 해주고, 그게 아니라면 pp에서 조정해주면 됌. 아래와 같은 세팅들이 있음
-Lumen Scene Lighting Quality
: 높을수록 정확도, 충실도 올라감
-Lumen Scene Detail
: 씬에서 계산될 수 있는 인스턴스의 사이즈를 관리함.
-View Distance
: GI를 위한 Sky Shadowing과 관련되어있음
-Lumen Reflections
: 값이 클수록 노이즈는 줄어들지만 GPU cost는 올라감. 아래 글 더 참조
-Final Gather Quality
: Lumen Scene에서 화면의 최종 픽셀로 빛을 전파하는 프로세스이다. 씬에 적합한 값으로 조절하면 되지만 높을수록 비싸다

- Hardware Raytracing을 켜면 훨씬 퀄리티가 올라가지만 그만큼 훨씬 비싸진다. 얘는 Screen Space로 작동되지 않아 실사와 더욱 가까운 라이팅이 가능하다. 프로젝트 세팅 > Support Hardware Raytracing을 먼저 켜서 프로젝트가 하드웨어 레이트레이싱을 지원하게 해주고 Use Hardware Raytracing when available을 켜서 루멘이 쓸 수 있게 해준다. PC의 경우 RTX 2000시리즈 이상이 필요하고 DirectX 12에서만 작동한다(2021 기준).
- Software Raytracing은 성능이 낮은 gpu에서도 루멘(레이트레이싱)이 돌아갈 수 있게 하려고 UE5에서 생긴 빌트인 레이 트레이싱이다. 실제 씬이 아니라 SDF로 구현된 simplified version을 추적한다 (Signed Distance Field는 3D의 볼륨으로 나타낸 것을 말함). SDF로 추적하면 추적이 빠르다. 이건 표시 > 시각화 > Mesh Distance Field로 확인할 수 있다. Software Raytracing이 일어나는 과정을 보면 Depth Buffer를 먼저 이용해서 트레이싱을 하고, 레이 미스가 날 경우(물체 통과, 화면 밖으로 나가버림..) SDF를 이용해서 트레이싱을 한다. SDF를 써도 Light를 계산하기 위해 추적할 때 surface의 hit된 모든 triangle을 샘플링하면 너무 비싸다. 그리고 GI를 계산하려면 머티리얼의 컬러나 들어오는 라이팅의 정보가 필요한데 Mesh Distance Field에는 Hit 지점과 노말 정보만 담겨있다. 그래서 생각해낸 방법이 Surface Cache다. 레이가 SDF에 히트하면 Surface Cache를 통해 라이팅을 구현한다. 이 과정을 거치는게 Software Tracing이다.
- Surface Cache는 nearby scene의 surfaces들의 parameterization(파라미터화) 한다. 그냥 메시를 다각도에서 저해상도로 캡쳐해서 Atlas의 형태로 갖고있다는 뜻임. atlas의 크기는 4096이다. 이 캐시는 레이가 포인트에 부딪힐 때 라이트와 표면 정보를 찾아준다. 유저가 움직일 때마다 계속 다시 캡처한다. 캐시이기 때문에 4096의 크기를 프레임마다 캡처하는 건 아니고 아주 작은 일부분만 캡처한다. 그리고 가까운 것은 고해상도로, 먼 곳에 있는 건 저해상도로 캡처한다. 저해상도로 캡쳐할 때 그 메시가 나나이트가 안 켜져있다면 캡처가 엄청나게 느려진다! 나나이트를 켜져있는 메시는 다시 캡처해서 계산할 때 10~100배 정도 빠르다고 한다. 그래서 나나이트는 언제 켜야하냐면 HighPoly 메시, 특히 Instanced Static Mesh에 루멘을 사용하려면 반드시 켜야 한다.  나나이트를 안켤려면 아주 좋은 LOD를 잘 세팅하면 된다. 그래도 인스턴스 스태틱 메시는 반드시 나나이트를 켜야한다. 루멘이 생기면서 작업방식이 달라진 것이 있다면 루멘과 나나이트는 쌍이라는 것이다! Surface Cache의 한계이자 루멘의 한계는 메시의 interior가 단순해야만 캐시가 작동한다는 것이다(2021 기준).그래서 제대로 작동하려면 오브젝트가 하나의 통째로 합쳐져있는 것보다 moduler 오브젝트처럼 조각조각으로 이루어져야 한다고 한다. 이 캐시는 GPU에 저장된다. 루멘은 이 캐시를 생성하기 위해 오브젝트 표면에 박스 모양으로 프로젝션(plane)을 배치한다.
- 이 프로젝션이나 캡처 위치를 Cards라고 한다. 이 카드는
r.Lumen.Visualize.CardPlacement 1
으로 확인할 수 있다. 이 카드를 이용해서 트라이앵글 메시를 렌더링해서 모든 머티리얼 프로퍼티(albedo, normal, Opacity, Depth..)를 여러 각도에서 캡처하여 atlas로 만든다. 이렇게 Card에는 Material Properties + Directional Lighting 정보가 담겨있다. 이렇게 Lumen은 SDF를 통해 Mesh 정보와 Cards 정보를 가지고 있게 된다. 이걸 가지고 루멘은 Direct와 Indirect Lighting을 계산한다. 이렇게 계산된 결과는 다음 프레임에 사용될 수 있도록 모든 Surface Cache에 전송된다.
- 그러나 Mesh 정보와 Cards 정보는 서로 다른 GPU에 저장된다. 이 둘은 합쳐서 생각하는게 좋은데 이게 Lumen Scene이다. 이건 표시 > 시각화 > Lumen Scene을 통해 볼 수 있다. 루멘은 이 정보를 통해 GI, 라이팅, 섀도우를 생성한다. Lumen Scene은 루멘의 레이트레이서가 보는 대상이다. 루멘 트레이서는 이렇게 보이고 이걸 바탕으로 계산하는 것. 리플렉션을 채크할 때 이걸로 봐도 된다
- Lumen Reflection. 이때까지 게임에서 라이팅과 리플렉션은 따로 계산되어 이를 일치시키는 작업이 필요했다. 하지만 루멘이 이를 합쳤다. GI 계산을 위한 트레이싱 정보를 리플렉션 계산에 재사용한다. 정확하기 때문에 이제 리플렉션 캡처를 배치할 필요가 없다. 리플렉션의 퀄리티를 더 높이고 싶다면 프로젝트 세팅 > Hardware Raytracing을 켜자. 또, PP > Lumen Reflection Quality는 기본 1이다. 라이팅 정보와 머티리얼 정보를 Surface Cache에서 샘플링한다. 2면 머티리얼 정보는 hit shader에서, 라이팅은 Surface Cache에서 샘플링한다. 4가 가장 높은데 머티리얼 정보뿐만 아니라 Direct Light도 hit shader에서 가져오고 Indirect Light만 Surface Cache에서 가져온다
-Distance Fields Resolution
: 이건 임포트한 스태틱 메시의 스케일을 기준으로 할당된다. 스태틱 메시를 더블클릭해서 열어보면 디테일 창에 Distance Field Resolution Scale 조절창이 있다. View모드를 Mesh Distance Field로 봤을 때 이상하게 나오는 경우가 있다면 이걸 바꿔주면 된다. 스케일 차이 때문에 그런 듯. 바꾸고 Apply Changes해서 조절해주면 된다.
- Global Distance Fields : 루멘은 정확도를 위해 처음 몇 미터는 각 Mesh Distance Field를 트레이싱 하고, 나머지는 각 레이의 Merge Distance Field(Global Distance Field)를 트레이싱한다. 그러면 멀리 있는 물체는 빠르게 트레이싱 할 수 있다. Show > 시각화 > Global Distance Field로 볼 수 있다. 이는 루멘이 자동으로 실행한다. 2m 안쪽은 mesh distance field, 2m 뒤쪽은 global distance field로 알아서 해준다
-Lumen Optimization
: Mesh Distance Field는 나나이트의 삼각형만큼은 아니더라도 꽤 정확하지만 트레이싱에는 비용이 따른다. 트레이싱 비용은 메시 수에 달려있다. 메시 수가 많을 때, 특히 메시가 서로 overlapping 되어있을 때 비싸진다. 최적화하는 방법으로는
1. 모든 메시 디스턴스 필드를 병합해 하나로 만든 Global Distance Field를 이용하는 것이다.
2. Surface Cache를 병합해서 SDF 등이 아니라 Voxel Lighting으로 바꾼다. 메시 디스턴스 필드를 병합한 것처럼 2D의 표면 라이팅도 복셀의 형태로 병합하는 것이다. 레이트레이싱은 훨씬 빨라지지만 정확도는 낮아진다.
3. 위에 나온 두가지 방법은 2m 이상 거리에서 자동으로 적용된다. 2m 안쪽에서는 개별 메시 별로 트레이싱을 하는 Detail Tracing, 2m 뒤 쪽은 통합된 Global Distance Field를 이용하는 Global Tracing이 이용된다. 이는 프로젝트 세팅 > Software Raytracing Mode에서 바꿀 수 있다. 이를 통해 메시가 많고 겹쳐있는 메시가 많은 복잡한 맵에서는 걍 통째로 global tracing으로 바꿔버릴 수 있다. 퀄리티는 떨어지더라도 퍼포먼스는 향상된다.
- 근데 할 수 있으면 bake하는 걸 추천한다고 함! 왜냐면 실시간 gi보다 굽는게 훨씬 실사에 가깝다고 함. 그대신 static하고 메시마다 light map이 필요함. 언리얼이 lightmap 생성이 잘 되어있다고는 함
-디렉셔녈 라이트 색상을 바꿀려면 구워서 쓰는 건 안될 듯. 실시간으로 해야지
- Hybrid Tracing : Lumen은 레이트레이싱 방법을 하이브리드한 방식을 이용해서 Realtime GI를 구현할 수 있게 되었다. Screen Trace + Mesh Distance Field Trace + Global Distance Field Tace를 혼합해서 쓰고 있다. 스크린 트레이싱의 경우 화면 밖에 있는 경우 추적을 할 수 없기 때문에 두번째 방법인 각 메시의 메시 디스턴스 필드를 이용해 추적한다. 얘는 스크린 밖에서도 작동하고 스크린 스페이스보다 신뢰도가 높다. 그치만 좀 비쌈. 그래서 레이가 멀리 나갈 때는 오브젝트 별이 아닌 모든걸 병합한 글로벌 디스턴스 필드를 이용해서 추적한다. 이 마지막 방법은 매우 빠르다. 이렇게 다양한 트레이싱의 조합으로 각 픽셀의 GI가 처리된다