파트 1에 이어 파트 2
파트 1은 여기.
다음으로 메쉬에 대해 조금 더 알아보겠습니다.
다음 문제는 삼각형 ID에서 정점과 인덱스를 가져오는 것입니다. 이를 위해서는 모든 메쉬를 여러 개의 작은 버퍼가 아닌 하나의 거대한 버퍼에 저장해야 합니다.
어쨌든 관리되는 거대한 버텍스 풀을 저장하는 것은 좋은 생각일 것입니다. 실제로 작년 프레젠테이션에서 HypeHype는 버텍스 또는 인덱스 버퍼를 전환하는 호출이 적었기 때문에 CPU 비용을 몇 사이클 줄일 수 있었습니다.
한 가지 까다로운 문제는 버텍스 애니메이션입니다. 각 픽셀은 세 개의 정점을 모두 읽어야 하며, 모델 행렬의 비용은 사소한 것으로 끝납니다. 하지만 복잡한 버텍스 애니메이션을 사용하면 비용이 폭발적으로 증가합니다.
따라서 프리패스를 실행하고 계산을 통해 위치를 저장해야 합니다. 렌더러에 따라 이 메모리 비용은 매우 고통스러울 수 있습니다. 하지만 메모리에 대한 비용을 지불하거나 성능에 대한 비용을 지불해야 할 것입니다. 하나를 선택하세요.
다음으로 논의해야 할 문제는 Derivatives(도함수)입니다.
앞서 설명한 내용에서 GPU가 왜 2x2 쿼드로 제한되는지 궁금해하셨을 텐데요, 그 이유는 바로 도함수 때문입니다. 텍스처 샘플을 수행할 때마다 GPU는 4개의 샘플을 사용하여 UV의 부분 도함수를 근사화합니다. 그래서 "헬퍼(Helper)" 레인이라고 불리는데, 활성 레인이 부분 도함수를 계산하는 데 도움을 줍니다.
이러한 파생물을 직접 계산해야 하며 Sample() 대신 SampleGrad()를 사용해야 합니다.
UV 도함수를 계산하기 위해 실제로 가장 먼저 필요한 것은 화면 공간에서 X와 Y를 기준으로 한 이심삼각의 부분 도함수입니다. 몇 년 전에 블로그 게시물에 관련 내용을 썼는데, 거기에서 실수가 있었던 것으로 밝혀졌습니다. 다행히 제임스 맥라렌과 스티븐 힐이 저에게 연락하여 올바른 버전이 여기에 나와 있습니다. 자유롭게 사용하세요. 엄밀히 말하면 블로그 게시물의 라이선스는 CC0이지만 문제가 있는 경우 저에게 핑을 보내주시면 원하는 라이선스로 사용할 수 있습니다.
이심삼각형의 부분 도함수를 구했으면 여기에 표시된 코드를 사용하여 속성의 부분 도함수를 계산할 수 있습니다.
논리적으로 도함수를 구성하는 가장 좋은 방법은 여기에 표시된 Derived_Float2와 유사한 구조를 사용하는 것입니다. 보간기에서 텍스처 샘플로 이어지는 임계 경로에 있는 모든 표현식은 이러한 구조를 사용하여 파생물을 끝까지 전달해야 합니다. 곱하기, 나누기 또는 기타 연산을 수행할 때마다 체인 규칙을 사용해야 합니다.
다음과 같이 코드를 수정해야 합니다. 원래 코드는 "uv = baseUv * scale"이지만, 대신 해당 함수의 파생된 버전을 사용해야 합니다. 그런 다음 Sample()을 사용하는 대신 SampleGrad()를 사용하고 분석 파생 함수를 전달해야 합니다.
하지만 머티리얼 그래프를 사용하는 경우 파생 노드를 유지 관리하고 파생 노드와 비파생 노드 간에 많은 변환을 수행하기 위해 코드 생성기를 변경해야 하므로 약간의 모험을 준비해야 합니다.
또는 MDL 또는 OSL과 같은 서피스 설명 API를 사용할 수도 있습니다. 두 가지 모두 MaterialX에서 생성할 수 있는 표면 설명 언어이며 파생물을 계산할 수 있습니다. MDL은 NVIDIA의 언어이고 OSL은 Sony Imageworks의 언어입니다. 둘 다 실행 가능한 옵션이지만, 저에게 있어 결정적인 차이점은 MDL에는 HLSL 백엔드가 포함되어 있지만 OSL에는 포함되어 있지 않다는 점입니다.
이것이 제가 사용해온 파이프라인입니다. USD에서 MaterialX로, MDL에서 HLSL로, 많은 작업이 필요할 것 같지만 전체 머티리얼 에디터를 작성하는 것보다 훨씬 적은 작업입니다. MDL에는 다른 유용한 기능도 몇 가지 있습니다.
마지막으로 살펴봐야 할 문제는 재구성 알고리즘입니다.
초기 샘플 포인트를 생성하는 방법에는 여러 가지가 있습니다. 첫 번째 접근 방식은 바둑판 접근 방식을 사용하는 것입니다.
두 번째 접근 방식은 1/4 속도로 이동하고 그리드를 절반 해상도로 사용하는 것입니다.
세 번째 옵션은 더 자세한 정보가 있는 곳에 더 많은 샘플을 얻기 위해 샘플을 편향시키는 확률적 접근 방식입니다.
마지막 접근 방식은 모든 샘플을 렌더링하는 것입니다.
핵심 요령 중 하나는 정확한 에지 감지를 수행하는 것입니다. 인스턴스 ID, 깊이 및 지오메트리 노멀을 사용하면 실제로 매우 우수한 에지 감지기를 얻을 수 있습니다.
임의의 위치를 재구성하려면 주변 영역을 4개의 영역으로 나누고 각 영역에 대해 하나의 픽셀을 선택할 수 있습니다.
예를 들어 회색 픽셀의 이웃을 찾고 싶다고 가정해 보겠습니다. 파란색 픽셀은 유효한 이웃이고 빨간색 선은 가장자리입니다.
이 경로를 사용하여 가장 좋은 이웃을 찾을 수 있습니다.
하지만 어떻게 하면 이 검색을 빠르게 수행할 수 있을까요? 시작 픽셀과 목표 픽셀이 주어지면 동일한 픽셀을 찾는 방법은 여러 가지가 있으며, 플러드 채우기는 너무 느립니다.
최적화를 위해 미리 지정된 검색 경로를 사용할 수 있습니다. 이론적으로 이 접근 방식은 일부 픽셀에 대한 유효한 경로를 놓칠 수 있지만, 픽셀을 찾기 위해 90도 회전을 여러 번 해야 한다면 이 방법은 좋은 후보가 아닐 수 있습니다.
이 패턴을 검색하는 가장 확실한 방법은 for 루프를 사용하는 것이지만, 실제로는 이진 표현식으로 최적화할 수 있습니다.
따라서 가운데 픽셀이 회색이라면 파란색 픽셀이 원하는 픽셀인지 확인하기 위해 거쳐야 하는 경로는 하나뿐입니다.
여기에는 세 가지 규칙이 있습니다.
첫째, 검색 경로로 가는 길에 유효한 픽셀이 없어야 합니다. 그렇지 않으면 파란색 픽셀이 아닌 분홍색 픽셀이 히트할 것입니다.
둘째, 가로 테두리가 없어야 합니다.
셋째, 경로를 따라 세로 테두리가 있어야 합니다.
이를 평가하는 가장 좋은 방법은 부울 표현식을 사용하는 것입니다. 여기에는 for 루프가 필요하지 않습니다.
부울의 가장 큰 장점은 인트로로 패킹할 수 있다는 것입니다. 검색 반경이 4픽셀에 불과하므로 양쪽에 4비트 패드를 사용하여 한 번에 24픽셀을 검색할 수 있습니다.
모든 검색 위치에 대해 이 거대한 부울 표현식을 평가한 후 각 차원에서 -4에서 +4 사이의 결과와 전혀 일치하지 않는 특수 값을 얻습니다. 그리고 4개의 방향을 하나의 32비트 정수에 담을 수 있습니다.
원하는 것보다 느리기 때문에 이 패스를 최적화하는 것이 제 할 일 목록에 있습니다.
알고리즘을 보여주기 위해 먼저 렌더링할 몇 가지 희박한 샘플을 선택했습니다.
그런 다음 수직 가장자리를 찾아야 합니다...
...그리고 가로 가장자리.
거기에서 경계를 넘지 않고 가장 좋은 4개의 히트를 사용하여 보간할 수 있습니다. 몇 개의 픽셀은 유효한 적중을 찾지 못하며 자세히 보면 빨간색으로 표시됩니다.
그런 다음 TAA를 적용할 수 있으며, 현재 프레임에서 적어도 하나의 이웃을 찾지 못한 픽셀을 무시할 수 있도록 TAA 알고리즘을 수정해야 합니다.
또한 완전 가변 비율은 조명이 변경될 때 TAA에 몇 가지 문제가 있습니다. 문제는 컬러 클램프에 사용되는 현재 프레임의 이웃 프레임이 매 프레임마다 변경되어 컬러 클램프가 일관되지 않다는 것입니다. 이로 인해 갑작스러운 빛의 변화로 아티팩트가 발생합니다. 이는 영원히 조정해야 하는 TAA 문제 중 하나입니다. 하지만 1배, 2배, 4배 패턴은 안정적으로 작동합니다.
이제 성능에 대해 이야기하면서 몇 년 전에 제가 수행한 몇 가지 합성 테스트부터 시작하겠습니다. 이 테스트에서는 복잡한 머티리얼과 삼각형의 크기를 미세하게 관리하기 위해 테셀레이션된 쿼드를 사용했습니다.
큰 트라이앵글을 사용한 테스트에서는 포워드와 디퍼드의 성능이 상당히 우수했습니다. V버퍼 패스는 머티리얼 및 라이팅 패스에서 약간 더 많은 비용이 들며, 데이터 관리를 위한 추가 패스가 있습니다. 이러한 씬에서 VBuffer는 약간의 성능 저하가 있습니다.
하지만 작은 1픽셀 삼각형을 사용하면 모든 것이 달라집니다. 머티리얼과 라이팅 패스를 결합하면 비용이 폭발적으로 증가합니다. 디퍼드 머티리얼 비용도 크게 증가합니다. 하지만 V버퍼 비용은 상대적으로 안정적으로 유지되므로 V버퍼가 확실한 승자입니다.
작은 트라이앵글과 큰 트라이앵글의 시간 비율을 보면 순방향 비용은 5.6배 느려지고 지연 패스는 4.3배 이상 느려집니다. 버텍스가 많을수록 대역폭과 캐시 미스가 많아지므로 V버퍼 비용은 약간 증가하지만 훨씬 더 안정적으로 유지됩니다.
그런 다음 VRS가 있는 작은 삼각형이 있으면 여기에 표시된 숫자가 나타납니다.
다음은 작은 삼각형에 대한 VRS와 비-VRS의 비용을 비교한 것입니다. 정방향의 경우 VRS의 이점이 없습니다. 흥미롭게도 지연 경로는 VRS를 사용할 때 그렇지 않을 때보다 실제로 더 느립니다. 하지만 V버퍼 접근 방식은 상당한 이득을 얻습니다. 우리가 원하는 이상적인 25% 비용에는 미치지 못하지만 여전히 꽤 괜찮은 수준입니다.
성능 수치를 확인하기 위해 원숭이 무리가 있는 테스트 장면을 사용할 수 있습니다. 이 메쉬는 메쉬옵티마이저의 자동 LOD를 사용하여 약 1m 트라이앵글로 세분화되어 있습니다. 하지만 실제로 LOD 0에 있는 메시는 없지만 6개는 500만 트라이에 해당하는 LOD 1에 있습니다.
숫자의 경우 프리패스, 섀도 패스는 중요하지만 생략하겠습니다. 하지만 모든 플랫폼에서 거의 동일합니다. 특히 프리패스에 노멀이 항상 필요하다고 가정한 이유는 DBuffer 데칼에 노멀이 필요하기 때문입니다.
포워드 렌더링을 사용하면 머티리얼과 라이팅 패스를 결합하는 데 약 2.47ms가 걸립니다.
GBuffer 접근 방식은 동일하게 보이며 1.94ms만 필요합니다.
VBuffer 룩은 총 1.67초가 소요됩니다.
2배 체커보드를 수행하려면 가장자리 감지 패스를 수행하고 재구성 패스를 적용해야 합니다. 총 시간은 1.44ms입니다.
절반 해상도 패스는 바둑판 패스와 유사한 에지 감지 패스가 필요합니다. 최적화할 시간이 없었기 때문에 전체 4개 영역 검색을 수행합니다.
마지막으로 완전 일반 스파스 샘플링 패스는 사용할 픽셀을 정렬하고 선택하기 위해 추가 작업을 수행해야 합니다.
일반적으로 1배의 V버퍼 접근 방식이 더 빠르며 디퍼드와 동일하게 보입니다. 머티리얼 평가 셰이더가 매우 가볍더라도 쿼드 점유로 인한 이점이 추가 패스 비용을 능가합니다. 가변 속도 이미지에는 이득이 있지만 매우 미미합니다.
이 표에서는 각 V버퍼 VRS 변형에 대해 머티리얼, 라이팅이 구분되어 있습니다. 기타는 "기타 모든 것"입니다. 매우 짧은 머티리얼 셰이더이지만 해상도가 감소함에 따라 머티리얼과 조명 비용이 꽤 잘 스케일링됩니다. 4배 VRS에서는 GPU를 바쁘게 할 만큼의 작업이 충분하지 않습니다.
전체적인 수치를 보면, 고사양 GPU에서 밀도가 높은 트라이앵글과 복잡한 머티리얼이 있는 씬은 VBuffer 렌더링으로 훨씬 더 잘 실행됩니다. 그러나 저성능 GPU의 덜 복잡한 씬에서는 VBuffer 렌더링의 오버헤드가 이점을 능가하기 때문에 VBuffer가 적합하지 않습니다.
하지만 여기에 문제가 있습니다. GPU는 매년 더 강력해지고 있습니다. 따라서 오버헤드 때문에 VBuffer가 순손실인 이 모든 경우에서 결국 GPU가 개선되고 VBuffer가 이득이 될 것입니다.
이것은 제 개인적인 의견이며, 여러분 스스로 동의하거나 동의하지 않을 수 있습니다. 하지만 VBuffer가 더 나은 접근 방식인가라는 질문을 하고 싶을 수도 있습니다.
하지만 이는 매우 주관적이고 편향된 제 의견이므로 회의적일 수밖에 없습니다. VBuffer가 더 나은 접근 방식입니다... 결국에는요. 하지만 결국에는 꽤 오랜 시간이 걸릴 수 있습니다. 따라서 올바른 질문은 VBuffer가 합당한 전환 시점이 언제인지, 그리고 그 전환을 어떻게 물류적으로 관리할 것인지입니다. 결국 우리 모두는 그 지점에 도달하겠지만, 그 길은 꽤 험난할 것이기 때문입니다.
즉, 이것은 100% 제 개인적인 의견이며, 이에 동의하지 않으셔도 좋습니다. 그리고 저는 VBuffer 렌더링이 얼마나 훌륭한지에 대한 프레젠테이션을 하고 있기 때문에 너무 편향되어 있으므로 제가 말하는 것을 믿거나 신뢰해서는 안 됩니다. 직접 수치를 실행해보고 결론을 내리세요.
마지막으로 OIT에 대해 잠시 이야기해 보겠습니다. 마무리하기 전에 OIT에 대한 몇 가지 흥미로운 기회와 프로토타입의 결과를 소개합니다. 완성된 제품이라고는 할 수 없지만 가능성을 보여주는 흥미로운 실험입니다.
다음은 토러스만 있는 전형적인 OIT 문제입니다. 위쪽에서 잘못된 블렌드 순서로 인한 아티팩트를 볼 수 있으며, 아래에서 이를 수정하는 방법을 확인할 수 있습니다. VRS로 VBuffer에 대한 모든 작업을 수행하면 OIT 지원을 추가하는 것은 실제로 쉽습니다. 어려운 부분은 다른 모든 부분입니다.
다음은 간단한 투명 메시의 다이어그램입니다. 이를 OIT로 어떻게 렌더링할까요?
레이어의 정확한 순서를 원하는 경우 일반적인 방법은 모든 샘플을 픽셀 단위로 연결된 목록에 저장하면서 메시를 렌더링하는 것이며, 이는 뎁스 필링을 대체하는 것으로 보입니다. 정확한 표현에 중점을 두었기 때문에 모멘트 기반 OIT는 여기서는 옵션이 아닙니다.
안타깝게도 샘플 수는 제한이 없습니다. 따라서 샘플 수가 무제한인 나쁜 카메라 앵글이 나올 수 있습니다. 이는 무한한 메모리와 무한한 성능 비용을 의미합니다.
그 대신 샘플 수에 엄격한 제한을 두겠습니다. 모든 픽셀에 대한 레이어 정보를 저장하는 대신 가능한 한 많은 픽셀에 대한 전체 레이어를 저장합니다. 나머지 픽셀에 대해서는 이웃 픽셀을 기준으로 보간합니다. 이 접근 방식은 메모리와 성능에 한계가 있지만 품질이 저하될 수 있습니다.
하지만 왼쪽에 또 다른 유효한 픽셀이 있다고 가정해 봅시다. 하지만 이 픽셀에는 2개의 샘플만 있기 때문에 옆에 있는 6개의 샘플이 있는 픽셀과는 상당히 다르게 보일 것입니다.
이 새로운 파란색 픽셀을 보간하려는 경우 문제가 됩니다. 6개의 샘플이 있으므로 6개의 샘플이 있는 오른쪽의 유사한 픽셀에서 보간하고 싶지만 2개의 샘플이 있는 왼쪽의 픽셀은 무시하고 싶습니다. 비결은 각 픽셀에 대한 해시를 계산하고 동일한 해시를 가진 주변 픽셀에서만 보간할 수 있다는 것입니다.
예를 들어, 원숭이들의 행렬을 투명하게 보여주는 다른 원숭이 행렬이 있습니다.
각 메시마다 고유 ID를 부여한 다음 해당 픽셀에 닿는 모든 샘플에 대해 해시를 증가시킬 수 있습니다.
다음은 실제 셰이더 코드입니다. 나중에 보실 수 있습니다. 모든 메시에는 16비트 ID가 있습니다. 모든 샘플에 대해 1의 값에 왼쪽으로 8비트 이동한 해시를 더합니다. 아래쪽 8비트는 개수를 저장하고, 중간 16비트는 고유한 해시를 저장하며, 위쪽 8비트는 오버플로를 방지하는 데 사용됩니다.
렌더링된 해시에서 하드 컷오프 이하로 유지하면서 가능한 한 많은 샘플을 선택합니다. 레이어 수가 증가함에 따라 픽셀은 점점 더 희박해집니다.
픽셀이 선택되면 유효한 픽셀에 대해 모든 가시성 샘플을 범프 할당할 수 있습니다.
OIT에 대한 실제 패스는 불투명 지오메트리에 대한 패스와 매우 유사합니다. 머티리얼별로 샘플을 정렬하고 GBuffer 데이터를 저장하는 각 머티리얼에 대해 간접 실행을 수행합니다. 그런 다음 불투명 패스와 마찬가지로 조명 패스가 있습니다. 에지 감지를 위해 깊이, 노멀, 인스턴스 ID 대신 해시를 사용할 수 있습니다. 그리고 재구성은 4개의 영역 각각에서 이웃을 선택합니다.
이것이 최종 알고리즘입니다. 해시를 래스터화하고, 하드 컷오프에 맞는 픽셀을 선택하고, 샘플 ID를 작성하고, 픽셀을 정렬하고, 색상을 계산 및 혼합하고, 보간한 다음 TAA를 적용합니다.
타이밍 비교를 보면 OIT 패스는 포워드보다 약간 낮을 뿐입니다. 즉, OIT 패스는 해상도가 훨씬 낮습니다.
가장 큰 문제는 패스가 너무 많다는 것입니다. 특별히 느린 패스는 없지만 모두 합산됩니다. 실제 라이팅/머티리얼 계산은 희소성 때문에 포워드 버전보다 훨씬 빠릅니다. 라이팅이나 머티리얼이 더 복잡하면 따라잡을 수 있지만 1밀리초의 추가 고정 비용은 엄청나게 큽니다.
몇 가지 흥미로운 이점이 있습니다. 메모리 크기가 보장됩니다. 머티리얼과 조명의 복잡성에 따라 잘 확장됩니다. 가장 큰 단점은 고정 비용이 많이 든다는 점입니다.
이 접근법의 진정한 장점은 아직 해결되지 않은 몇 가지 문제를 해결할 수 있는 디딤돌이 될 수 있다는 점입니다. 알고리즘이 깊이 정보를 저장하기 때문에 레이마칭을 사용하여 임의의 굴절을 구현할 수 있습니다. DOF와 같은 어려운 문제를 투명도로 해결할 수 있을 것입니다.
이 모든 것은 제 초기 사용 사례로 거슬러 올라갑니다. 에셋이 오프라인 경로 트레이서용으로 디자인된 경우 실시간 렌더러와 정확한 품질을 일치시키는 것은 현실적으로 불가능합니다. OpenPBR은 굴절을 지정하는데, 실시간 모드에서 굴절을 끄는 것보다 더 나은 옵션이 있으면 좋을 것 같습니다. 굴절과 피사계 심도와 같은 문제를 일반적인 방식으로 해결할 수 있다면 "그냥 작동하는" 합리적인 근사치를 만들 수 있을 것입니다. 저는 스파스 OIT가 그 방향으로 나아가는 한 걸음이 될 수 있기를 바랍니다.
마지막으로 유니티의 많은 분들께 감사의 말씀을 전하고 싶습니다.
나중에 슬라이드를 보실 때를 대비하여 VBuffer 참조를 소개합니다.
그리고 강연의 다른 참고 자료도 참고하세요,
REFER - VBUFFER
Burns and Hunt, The Visibility Buffer: A Cache-Friendly Approach to Deferred Shading, JCGT 2013
https://jcgt.org/published/0002/02/04/paper.pdf
Schied and Dachsbacher, Deferred Attribute Interpolation for Memory-Efficient Deferred Shading, HPG 2015
https://cg.ivd.kit.edu/publications/2015/dais/DAIS.pdf
Engel, Triangle Visibility Buffer, 2018
https://diaryofagraphicsprogrammer.blogspot.com/2018/03/triangle-visibility-buffer.html
Karis, Stubbe, Wihlidal, Nanite, A Deep Dive, SIGGRAPH 2021: Advances in Real Time Rendering in Games
https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf
Hable, Visiblity Buffer Rendering with Material Graphs, 2021
http://filmicworlds.com/blog/visibility-buffer-rendering-with-material-graphs/
Drobot, Geometry Rendering Pipeline Architecture, REAC 2021
https://research.activision.com/publications/2021/09/geometry-rendering-pipeline-architecture
McLaren, Adventures with Deferred Texturing in Horizon Forbidden West, 2022
https://www.guerrilla-games.com/read/adventures-with-deferred-texturing-in-horizon-forbidden-west
too_much_voltage, Faster Visibility Buffer/Deferred Material Rendering via Analytical Attribute Interpolation using Ray Differentials, 2022
https://www.reddit.com/r/GraphicsProgramming/comments/uf4ykj/faster_visibility_bufferdeferred_material/
Erler and Engel, Triangle Visibility Buffer 2.0, I3D 2024
https://www.youtube.com/watch?v=kWLev9CoQdg
JMS55, Virtual Geometry in Bevy 0.14, 2024
https://jms55.github.io/posts/2024-06-09-virtual-geometry-bevy-0-14/
Li and Cao, SmartGI Evolution: Adaptive NanoMesh on Mobile, GDC 2024
https://www.youtube.com/watch?v=yD5DjNyiYIQ
REFER - VRS
Drobot, Hybrid Reconstruction Anti-Aliasing, SIGGRAPH 2014: Advances in Real-Time Rendering in Games
https://advances.realtimerendering.com/s2014/index.html#_HYBRID_RECONSTRUCTION_ANTI-ALIASING
Mallet and Yuksel, Deferred Adaptive Compute Shading, HPG 2018
https://geometrian.com/data/research/dacs/HPG2018_DeferredAdaptiveComputeShading.pdf
Intel, Get Started with Variable Rate Shading on Intel® Processor Graphics, 2019
https://www.intel.com/content/www/us/en/developer/articles/guide/getting-started-with-variable-rate-shading-on-intel-processor-graphics.html
Van Rhyn, Variable Rate Shading: a scalpel in a world of sledgehammers, 2019
https://devblogs.microsoft.com/directx/variable-rate-shading-a-scalpel-in-a-world-of-sledgehammers/
du Bois and Gibson, Variable Rate Shading Tier 1 with Microsoft DirectX 12 From Theory to Practice, GDC 2020
https://www.youtube.com/watch?v=d-qEvmVcg8I
Drobot, Software-based Variable Rate Shading in Call of Duty: Modern Warfare, SIGGRAPH 2020: Advances in Real Time Rendering in Games
https://research.activision.com/content/atvi/activision/research/web/en/publications/2020-09/software-based-variable-rate-shading-in-call-of-duty--modern-war
Mallet, Yuksel, and Seiler, Efficient Adaptive Deferred Shading with Hardware Scatter Tiles, ACM Computer Graphics and Interactive Techniques, 2020
https://dl.acm.org/doi/abs/10.1145/3406184
Van Rhyn, Moving Gears to Tier 2 Variable Rate Shading, 2021
https://devblogs.microsoft.com/directx/gears-vrs-tier2/
Hable, Software VRS with Visibility Buffer Rendering, 2021
http://filmicworlds.com/blog/software-vrs-with-visibility-buffer-rendering/
Fuller, Variable Rate Compute Shaders - Halving Deferred Lighting Time, 2022
https://www.youtube.com/watch?v=Sswuj7BFjGo
Whilidal, Nanite GPU-Driven Materials, GDC 2024
https://schedule.gdconf.com/session/nanite-gpu-driven-materials/899486