ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [번역] Journey to Lumen
    Graphics/번역 2022. 10. 9. 16:33

    개인 공부용으로 번역한 거라 잘못 번역된 내용이 있을 수 있습니다.
    또한 원작자의 동의 없이 올려서 언제든 글이 내려갈 수 있습니다.
    출처 : https://knarkowicz.wordpress.com/2022/08/18/journey-to-lumen/

    Journey to Lumen

     

    Real-time GI 는 항상 컴퓨터 그래픽스의 성배였습니다. 몇년동안 이 문제에 대해서 여러가지 접근법이 있었습니다. 보통은 static geometry, too coarse scene presentation 또는 coarse probes 를 사용한 tracing 그리고 lighting 들간에 보간과 같이 특정 가정을 사용하여 문제의 범위를 제한합니다. Daniel Wright 와 Lumen 을 시작할 때, 우리의 목표는 라이트를 통합하고 baked lighting 과 비슷한 품질을 얻을 수 있는 것이었습니다. 그것은 이전에 누군가 봤었던 것과 같은 타협이 거의 없는 해결법을 만드는 것입니다.


    다른 새로운 시스템과 같이, 우리는 많은 것을 시도했습니다. 그 중 일부는 막다른 길이 었으며 우리는 접근법을 수정하고 다른 것을 시도해야 했습니다. 우리는 우리의 여정을 SIGGRAPH 2022 talk 에서 다뤘습니다, 그러나 90 분은 Lumen 이 어떻게 동작하는지를 보여주기에 충분하지 않았습니다. 이 글은 우리의 버려진 기술을 다룰 것이고 우리가 SIGGRAPH 에서 보여준 해결법으로의 여정을 보여줄 것입니다.

     

    Software Ray Tracing Representation

    우리가 Lumen을 시작했을 때, 하드웨어 Raytracing 이 발표되었습니다, 그러나 GPU 지원은 없거나 구체적인 성능 수치도 없었습니다. 현재의 콘솔 세대는 분명히 막이내리고 있었고, 다음 세대의 콘솔로 가는 길목에 있었습니다, 그러나 우리는 하드웨어 Raytracing이 얼마나 빠를지 또는 콘솔에서 지원될지 여부도 몰랐습니다. 이런 것들은 우리가 현실적인 소프트웨어 Raytracing 접근법을 먼저 둘러보도록 하였습니다, 이것은 이후에 수많은 인스턴스들이 겹쳐있고 그것이 고정된 2 단계의 BVH 에 의해 처리되는 장면을 축소하거나 지원을 위한 훌륭한 도구임이 입증되었습니다.


    소프트웨어로 tracing 하는 것은 triangles, distance fields, surfels or heightfiels 와 같은 다양한 tracing 구조를 사용할 수 있는 가능성을 열어줍니다. 우리는 triangles 는 버렸습니다. 왜냐하면 하드웨어 해결법을 이길 수 없기 때문입니다. 우리는 간단히 surfels 를 봅니다, 그러나 surfels 는 지오메트리를 표현하는데 상당히 고밀도로 필요했습니다. 그리고 많은 surfels 를 갱신하거나 tracing 하는 비용은 상당히 비쌌습니다.


    Heightfields

    첫 탐험 후에 가장 유망한 후보는 Heightfield 였습니다. Heightfields 하드웨어와 잘 매핑되고, 작은 표면 표현과 simple continuous LOD를 제공합니다. 그들은 tracing 하는데 꽤 빠릅니다, 왜냐하면 우리는 min-max quadtrees 와 같은 모든 POM  알고리즘을 사용할 수 있기 때문입니다. 여러 Heightfields 는 Rasterized Bounding Volume Hierarchies 와 비슷하게 복잡한 지오메트리를 표현할 수 있습니다.


    그것들을 surfels 의 가속 구조로 생각하는 것도 흥미롭습니다, 단일 텍셀은 regular grid 에 제한된 한개의 surfel 입니다. 이것은 빠른 갱신과 tracing 그리고 더 낮은 메모리 오버헤드를 위해서 자유로운 배치를 맞바꿉니다.


    Heightfield 와 동시에 우리는 알베도나 라이팅 같은 다른 속성 또한 저장했습니다, 이것은 라이팅을 매 hit 마다 계산 할 수 있게 해주었습니다. 이 표면데이터를 가진 전체 데칼 같은 프로젝션은 루멘에서 우리가 card 로 이름 붙였습니다.

    Raymarched cards (Heightfields)

    Card는 opacity 또한 저장합니다. 이것은 그들에게 구멍을 만들 수 있게 해 줍니다 - 체인으로 연결된 울타리 같은 것을 생각해보세요. 하드웨어 bilinear interpolation 으로 유효하지 않은 depth 값을 가진 전체적으로 투명 텍셀로부터 모든 샘플을 보간할 수 있습니다. 우리는 ray marcher 의 내부 루프 안에서 수동으로 bilinear interpolation 을 수행하고 싶지 않습니다, 그래서 대신에 우리는 card 를 캡쳐하는 동안 depth value 를 확장했습니다.

    Before and after card depth dilatation

    모든 ray에 대해서 장면내 모든 card 를 ray marching 하기에는 너무 느릴 것입니다. 우리는 card 를 위한 가속 구조와 같은 것이 필요했습니다. 우리는 4-node BVH 로 결정했습니다, 그것은 전체 장면에 대해서 CPU 에서 매프레임 생성하고 이것은 GPU 에 업로드됩니다. 그러고 나서 tracing shader 내에서 가장 가까운 것을 먼저 순회하기 위해서 즉석에서 정렬한 노드로 stack 기반 순회를 할 것입니다.

    Heightfield BVH debug view

    Card Placement

    까다로운 부분은 전체 메시를 캡쳐하기 위해서 Heightfield 를 배치하는 방법입니다. Global distance field 기반으로 GPU 기반 배치를 만드는 것입니다. 우리는 card 에 대해 커버되지 않는 ray 히트를 찾기 위해서 매프레임 작은 세트의 primary rays 를 tracing 합니다. 다음으로 커버되지 않은 모든 hit 에 대해서 새로운 카드를 생성할 목적으로 우리는 최적의 card 방향과 범위(extent) 를 알아내려고 표면의 기울기를 사용하여 global distance field 를 수행합니다.

    Global distance field based card placement

    이것은 당신이 메시당 card 를 생성하는 대신에 전체 병합된 장면에 대해서 card 를 생성하게 해주기 때문에 성능이 아주 좋습니다. 불행히도 그것은 실제로 꽤 까다로운 것으로 드러났습니다, 왜냐하면 카메라가 이동할 때마다 다른 결과가 생성되었기 때문입니다.

    다음 아이디어는 메시를 임포트하는 단계에서 card 를 메시당 배치하는 것입니다. 우리는 지오메트리의 BVH 를 생성했습니다, 여기서 모든 노드는 N 개의 카드로 변환됩니다.

    Rasterized triangles
    Raymarched cards (Heightfields)
    Card placement view

    이 접근은 좋은 배치를 찾는 것에 이슈가 있습니다, BVH 노드가 card 를 배치하기 위한 괜찮은 프록시가 아니라는 것을 알게 되었기 때문입니다.
    다음 아이디어는 UV unwrapping 기술을 따르는 것과 surface element 를 클러스터링 하는 것이었습니다. 우리는 삼각형을 surfel 로 전환했습니다, 왜냐하면 이 시점에서 Nanite에 의해 수백만개의 폴리곤을 처리하는게 명백하게 필요하기 때문입니다. 또한 우리는 표면과 잘 일치시키기 위해 방향 제약이 덜한 card 로 전환했습니다.

    Freely oriented card placement

    이것은 간단한 shape 에는 잘 동작했지만 더 복잡한 shape 에서는 수렴(coverging)하는데 문제가 있었습니다, 그래서 우리는 마지막에 다시 축정렬 된(axis-aligned) card 로 전환하였습니다.

    Cone Tracing

    Heightfield tracing의 독특한 특성은 우리가 cone tracing을 할 수도 있다는 것입니다. Cone tracing은 어떠한 denosing 없이도 noise 감소에 아주 좋습니다, 왜냐하면 pre-filerted single cone tracing은 수천개의 개별 ray로 표현되기 때문입니다. 이것은 우리가 강한 denoiser 가 필요하지 않을 것이고 고스팅으로 인한 모든 이슈를 피할 수 있다는 의미입니다.

    Ray tracing
    Cone tracing

    모든 card 에 대해서 우리는 surface height, lighting 그리고 material properties 를 full pre-filtered mip-map chain 에 저장합니다. tracing할 때, cone 은 cone 범위를 기반으로 적절한 mip level 을 선택하고 ray marching을 합니다. Cone 은 card 에 의해서 완전히 가려질 필요가 없습니다, 그래서 우리는 card 테두리까지의 거리와 표면의 투명도를 사용하여 partial cone occlusion 을 근사했습니다.

    Tracing without and with card borders

    Cone tracing은 가볍지 않았습니다, 모든 단계에서 partial surface hit 이 생길 수 있었고, 그 다음에는 그에따라 미래에 있을 특정 hit 가 막혀야 하기 때문입니다. 이런 partial cone occlusion 추적은 여러개의 Heightfield 로 더 복잡해 집니다, 왜냐하면 Heightfield 는 ray 별로 depth 가 정렬되어있지 않고 일반적인 경우 정렬 할수 없기 때문입니다, 때문에 그들을 서로 교차할 것입니다. 이것은 기본적으로 또 다른 크고 풀리지 않은 렌더링 문제입니다. - unordered transparency.

    우리의 해결법은 card 가 겹치지 않는다고 가정하고 오클루젼을 누적하는 것입니다, 왜냐하면 우리는 누출(leaking) 되는 것 보다는 과도하게 오클루젼되는 것을 더 낫다고 생각하기 때문입니다. Radiance 누적에 대해서 우리는Weighted Blended OIT 를 사용하였습니다. 흥미롭게도 Weighted Blended OIT 는 넓은 Depth 범위 때문에 Primary ray에서 상당한 양의 누출(leaking)이 발생한 반면 짧은 GI ray에는 잘 동작했습니다.

    Weighted blended OIT with a narrow cone
    Weighted blended OIT with a wide cone

     

     

    Merged Scene Representation

    소프트웨어에서 수많은 비일관된(incoherent) tracing 할 ray를 가지는 것은 상당히 느린 것으로 입증되었습니다. 이상적으로는 여러 Heightfield 대신에 ray당 single global structure 를 Raymarching 할 것입니다.

    우리는 cone 범위가 더 넓어질 수록 정밀한 장면의 표면이 필요하지 않으며 더 근사된 것으로 전환가능하고 더 빨라진다는 중요한 깨닳음을 얻었습니다.

    A bit more complex scene with dozens of cards to trace per ray

    첫번째 성공적인 접근은 순수한 voxel cone tracing 을 구현하는 것이었습니다, 거기서 전체 장면은 실시간으로 복셀화 됩니다. 그리고 우리는 "Interactive Indirect Illumination Using Voxel Cone Tracing" 논문과 같은 고전적인 방법으로 그것을 Raymarching 합니다.

    또한 여기가 루멘에서 연속 tracing 개념이 태어난 곳입니다. 우리는 먼저 짧은 거리를 Heightfield tracing 하고난 뒤 필요한 경우 ray를 계속진행하기 위해서 voxel cone tracing으로 전환 합니다.

    Rasterized triangles
    Raymarched cards (Heightfields)
    Voxel cone tracing
    Raymarched cards continued with voxel cone tracing

    Voxel cone tracing의 주요 단점은 장면 지오메트리의 공격적인 병합으로 인한 누출(leaking) 입니다, 이것은 더 낮은 mip-map 을 tracing 하는 경우 보입니다. 이런 병합된 표현은 이후에 이웃 voxel 간에는 공간적으로 그리고 근처 이웃 voxel 의 면 사이는 각도를 기반으로 보간됩니다.

    첫번째 누출(leaking) 감소 기술은 global distance field 를 tracing 하는 것과 voxel volume 의 근처 표면만 샘플링 하는 것입니다. 샘플링 하는 동안 우리는 radiance 와 함께 opacity 를 누적할 것입니다. 그리고 opacity 가 1 에 달하면 tracing을 멈춥니다. 항상 정확하게 지오메트리에 근접한 Voxel volume 을 샘플링 하는 것은 얇은 solid wall 에서 cone 을 멈출 기회를 늘려줍니다.

    두번째 기술은 메시의 내부를 복셀화 하는 것입니다. 이것은 두꺼운 벽에서의 누출(leaking)을 크게 감소시킵니다만 몇몇 과도한 오클루젼을 일부 유발합니다, 왜냐하면, 이제 우리는 부정확하게 전체 에너지를 감소시키는 radiance 가 0 인 복셀 표면 를 보간하고 있습니다.
    Distance field 와 함께 하더라도 우리는 여전히 누출(leaking)을 다양한 곳에서 볼 수 있었습니다, 그래서 만약 우리가 distance field ray hit 가 등록되면 cone tracing 을 강제로 종료하였습니다. 이것은 누출(leaking)을 최소화합니다, 그러나 더 많은 과도한 오클루젼과 cone tracing을 한다는 아이디어와 다소 모순되었습니다.

    몇몇 다른 실험에는 sparse voxel bit 블록과 각 면당 투명한 채널을 가진 voxel 을 추적하는 것이 포함되어 있습니다. 두 실험 모두 Ray 방향 voxel 보간 문제를 해결하기 위해서 설계되었습니다. 여기서 정렬된 solid 벽 이 벽에 대해서 수직이 아닌 Ray 에 대해서 투명해집니다.

    Voxel bit 블록은 8x8x8 블록에서 주어진 복셀이 비어있는지 아닌지 여부를 위해 voxel 당 1 비트에 저장됩니다. 그리고나서 우리는 2 단계의 DDA 알고리즘을 사용하여 그들을 ray marching 하였습니다. 투명한 면을 가진 voxel 은 유사하지만, 단일 단계의 DDA 만 있었고 ray 를 따라서 투명도를 누적하였습니다. 두 접근법 모두 distance field 보다 geometry 를 표현하는 것이 덜 효과적이고 빈 공간을 건너뛰는 것도 잘 되지 않아서 상당히 느렸습니다.

    Voxels with transparency

    병합된 표현을 tracing 하는 가장 최초의 접근은 global distance field 를 cone tracing  하고 hit 한 것을 전역으로 사용하는 장면 별 card 를 사용하여 쉐이딩 하는 것입니다. 구체적으로 우리는 BVH 에서 장면 내에서 우리가 hit 한 위치에 영향을 주는 card 를 찾기 위해 순회하고 cone 의 범위를 기반으로 매번 card 의 적절한 mip level 을 샘플링합니다.

    Raymarched cards
    Raymarched global distance field with hit lighting from cards

    우리는 이 접근을 버렸습니다. 왜냐하면 원거리 tracing 표현에만 사용할 것을 생각하지 않았으며 대신에 highfield ray marching 을 위한 직접적인 대체물로 생각했습니다. 아이러니하게도 이런 폐기된 접근 방식은 2년 후에 접근한 최종 해결책과 가장 가까웠습니다.


    Shipping First Demo

    이 시점에서 우리는 꽤 좋은 결과를 만들 수 있었습니다:

    여전히, 우리는 누출(leaking) 이슈가 있었고, 간단한 장면의 성능은 심지어 PC GPU 에서도 이상적이지 않았습니다:
    Radeon RX Vega 64 at 1080p
    3.86ms Radiosity
    2.26ms DirectLighting
    8.48ms Prefilter / Voxel injection
    5.50ms LightCardDiffuseGI 
    5.46ms LightCardReflections 
    Total 25.56ms
     
    이것은 우리의 첫번째 월드의 실제 사용 사례 작업했을 때의 초기 상태입니다 - “Lumen in the Land of Nanite” 테크데모. 우리는 누출(leaking) 문제를 해결하고, x100 더 많은 인스턴스를 처리하는 것을 PS5 에서 8ms 내에 해야 했습니다. 이 데모는 Lumen 2.0 의 진정한 기폭제이고 강제로 작업의 결과를 만들게 하는 중요한 이벤트(forcing-function) 이었습니다.

    첫번째이자 가장 큰 변화는 Heightfield tracing 과 distance field tracing 을 함께 하는 것이었습니다. hit point 를 쉐이딩 하기 위해서 우리는 card 에서의 hit point 에 라이트를 보간하였습니다. 왜냐하면 distance field 는 vertex attributes 가 없었고 material 을 평가할 수 없었기 때문입니다. 이 변화로, 적용 범위가 누락된 영역에는 leaking 대신 에너지 손실만 발생합니다.

    같은 개념으로 voxel cone tracing 은 global distance field ray tracing 으로 변경되었습니다. 그리고 병합된 card volume 으로 부터 hit 지점에 쉐이딩을 하였습니다.

    우리는 여전히 card 에 full mip-map hierarchy 를 사용하여 prefiltering 을 사용하였고 ray 범위(footprint)를 기반으로 적절한 mip 을 사용했습니다, 그러나 이후에 우리는 다른 tracing 이 그렇지 않을때(screen space 같이) 일부 tracing 유형만 prefilter 하는 것은 실제로 도움이 되지 않는 것을 알게 되었습니다. 추가적으로 sky cubemap 에 대해서만은 어떤 종류의 prefiltering 들이라도 leaking 을 더 많이 만들었습니다. 왜냐하면 이제는 보이지 않는 texels 도 모으고 있었기 때문입니다.

    이와 함께 캐싱 체계를 통해 다양한 최적화 또한 했고, 루멘의 다른 부분을 시분할(time-spliced) 처리했습니다. 특히 cone tracing 없이 우리는 더 공격적인 denoise 와 cache tracing 를 해야만 했습니다, 그러나 이것은 또다른 길고 복잡한 이야기 입니다. 이 글의 범위를 벗어났을 뿐만 아니라, 내가 그것에 대해 글을 쓸 사람도 아닙니다.

    Global distance field 와 같은 모든 공유 데이터 구조의 업데이트를 포함하여 PS5 에서 루멘이 8ms 미만으로 유지되는 상태로 출시한 최종결과인 첫번째 데모입니다. 요즘 이런 수치는 심지어 더 좋아졌습니다, 왜냐하면 우리는 이 데모에서 4ms 에 근접했고 다양한 퀄리티 향상이 있었기 때문입니다.

    Epilogue

    꽤 긴 여정이었습니다 - 다양한 이론적인 아이디어와 많은 프로토타입들 부터 출시 가능한 것들로 부터요. 우리는 전체 루멘을 완전히 다시 작성했고 아직 테스트 해보지 못한 수많은 다른 아이디어를 갖고 있습니다. 반면 어떤 것은 용도가 변경되었습니다. 예를들면 초기에 우리는 card 를 tracing 표현에 사용했지만  이제는 그것을 메시 표면에서 다양한 계산을 캐싱해두기 위한 방법으로 사용합니다. 비슷하게 software tracing 에서는 우리의 주요 tracing 방법으로써 cone tracing 아이디에 확신을 갖고 시작했지만, 결국에는 그 방법을 축소하고 겹쳐지는 인스턴스가 많은 복잡하고 무거운 장면을 지원하는 것으로 결정했습니다.
    SIGGRAPH Advacnes talks 에서 우리가 루멘에서 도달한 곳에 대해 더 많은 알수 있습니다:
    “Radiance Caching for Real-Time Global Illumination”
    “Lumen: Real-time Global Illumination in Unreal Engine 5”

     

    댓글

Designed by Tistory & scahp.