가상 텍스처링은 실제로 어떻게 효율적일 수 있습니까?


27

참고로, 제가 언급하고있어 IDTECH 5의 도입 첫번째 기술에 대한 "일반적인 이름"(내가 믿는)입니다 MegaTexture의 기술. 작동 방식에 대한 간략한 정보는 여기 비디오를 참조하십시오 .

최근에 관련된 논문과 출판물을 훑어 보았지만 이해하지 못하는 것은 어떻게 효율적일 수 있는지에 대한 것입니다. "글로벌 텍스처 페이지"공간에서 가상 텍스처 좌표로 UV 좌표를 지속적으로 다시 계산하지 않아도됩니까? 그러면 배치 배치 형상에 대한 대부분의 시도가 어떻게 완전히 억제되지 않습니까? 임의 확대를 허용하는 방법은 무엇입니까? 어느 시점에서 다각형을 세분화해야합니까?

이해가 안되는 부분이 많으므로 주제에 대해 실제로 쉽게 접근 할 수있는 리소스를 찾을 수 없었습니다.

답변:


20

개요

VT (Virtual Texturing) 또는 Sparse Virtual Textures 의 주된 이유 는 메모리 최적화입니다. 중요한 것은 렌더링 된 프레임에 필요할 수있는 실제 텍셀 (페이지 / 타일로 일반화 됨) 만 비디오 메모리로 이동하는 것입니다. 따라서 비디오 메모리 나 주 메모리에 비해 오프라인 또는 느린 스토리지 (HDD, 광학 디스크, 클라우드)에 훨씬 더 많은 텍스처 데이터를 가질 수 있습니다. 최신 운영 체제에서 사용되는 가상 메모리 의 개념을 이해하면 본질적으로 동일합니다 (이름은 우연히 표시되지 않음).

VT는 메시를 렌더링하기 전에 각 프레임에서 수행 한 다음 정점 데이터를 다시 제출한다는 점에서 UV를 다시 계산하지 않아도되지만 들어오는 UV에서 간접 조회를 수행하려면 정점 및 조각 쉐이더에서 상당한 작업이 필요합니다. 그러나 좋은 구현에서는 가상 텍스처 또는 전통적인 텍스처를 사용하는 경우 애플리케이션에 대해 완전히 투명해야합니다. 실제로, 대부분의 경우 응용 프로그램은 가상 및 전통적인 텍스쳐링 유형을 혼합합니다.

배칭은 이론적으로는 잘 작동하지만, 이것에 대한 세부 사항은 한번도 보지 못했습니다. 지오메트리 그룹화에 대한 일반적인 기준은 텍스처이며 VT에서는 장면의 모든 다각형이 동일한 "무한한 크기"텍스처를 공유 할 수 있습니다. 이론적으로는 1 회 호출로 전체 장면 그리기를 달성 할 수 있습니다. 그러나 실제로는 비실용적 인 다른 요인들이 작용합니다.

VT 관련 문제

VT 설정에서 확대 / 축소 및 카메라 움직임의 급격한 처리가 가장 어렵습니다. 정적 장면에서는 매우 매력적으로 보일 수 있지만 일단 움직이기 시작하면 외부 저장소로 스트리밍 할 수있는 것보다 더 많은 텍스처 페이지 / 타일이 요청됩니다. 비동기 파일 IO 및 스레딩이 도움이 될 수 있지만 게임과 같은 실시간 시스템 인 경우 고해상도 타일이 도착할 때까지 저해상도 타일로 몇 프레임을 렌더링해야합니다. 텍스처가 흐릿합니다. 여기에는 총알이 없으며 IMO 기술의 가장 큰 문제입니다.

가상 텍스처링은 투명도를 쉽게 처리 할 수 ​​없으므로 투명한 다각형에는 별도의 전통적인 렌더링 경로가 필요합니다.

VT는 흥미롭지 만 모든 사람에게 추천하지는 않습니다. 그것은 잘 작동 할 수 있지만 구현하고 최적화하기가 어렵고, 내 취향에 필요한 코너 케이스와 사례 별 조정이 너무 많습니다. 그러나 대규모 오픈 월드 게임 또는 데이터 시각화 앱의 경우 모든 컨텐츠를 사용 가능한 하드웨어에 맞추는 유일한 방법 일 수 있습니다. 많은 작업으로 PS3 및 XBOX360 버전의 id 's Rage 에서 볼 수 있듯이 제한된 하드웨어에서도 상당히 효율적으로 실행할 수 있습니다 .

이행

OpenGL-ES를 사용하여 iOS에서 VT를 어느 정도까지 작동시킬 수있었습니다. 내 구현은 "배송 가능"하지 않지만 리소스를 원하고 가지고 있다면 구현할 수 있습니다. 여기에서 소스 코드를 볼 수 있습니다 . 조각이 어떻게 맞는지 더 잘 알 수 있습니다. iOS Sim에서 실행되는 데모 비디오다음과 같습니다 . 시뮬레이터가 쉐이더를 에뮬레이트하는 것이 끔찍하기 때문에 매우 게으르지 만 장치에서 부드럽게 실행됩니다.

다음 다이어그램은 구현에서 시스템의 주요 구성 요소를 간략하게 설명합니다. Sean의 SVT 데모 (링크 다운 벨로우즈)와는 약간 다르지만 , 첫 번째 GPU Pro 책 (링크 벨로우즈)에있는 CUDA를 사용한 가상 텍스처링 가속 (Accelating Virtual Texturing Using CUDA )에서 제시 한 것과 비슷 합니다.

가상 텍스처링 시스템

  • Page Files사전 처리 단계로 이미 타일 (AKA 페이지)로 잘라낸 가상 텍스처이므로 필요할 때마다 디스크에서 비디오 메모리로 이동할 수 있습니다. 페이지 파일에는 가상 밉맵 이라고도하는 전체 밉맵 세트가 포함되어 있습니다 .

  • Page Cache ManagerPage TablePage Indirection텍스처 의 응용 프로그램 측 표현을 유지합니다 . 오프라인 저장소에서 메모리로 페이지를 이동하는 데 많은 비용이 소요되므로 이미 사용 가능한 항목을 다시로드하지 않도록 캐시가 필요합니다. 이 캐시는 매우 간단 최소 최근 사용 (LRU) 캐시. 캐시는 또한 데이터의 자체 로컬 표현으로 물리적 텍스처를 최신 상태로 유지하는 역할을하는 구성 요소입니다.

  • Page Provider장면의 주어진보기에 필요한 페이지를 가져올하고이 캐시로 보내드립니다 비동기 작업 큐입니다.

  • Page Indirection질감은 들어오는 UV를 매핑합니다 가상 질감의 각 페이지 / 타일 하나 개의 픽셀과 질감입니다 Page Table실제 텍셀 데이터가 캐시 텍스처. 이 텍스처는 상당히 커질 수 있으므로 RGBA 8 : 8 : 8 : 8 또는 RGB 5 : 6 : 5와 같은 컴팩트 한 형식을 사용해야합니다.

그러나 여기서 중요한 부분이 여전히 누락되어 있으므로 저장소에서 캐시로로드되어야하는 페이지를 결정하는 방법 Page Table입니다. 곳이다 피드백 패스 와이 (가) Page Resolver입력합니다.

피드백 패스는 커스텀 셰이더와 훨씬 낮은 해상도로 뷰의 사전 렌더링으로 필요한 페이지의 ID를 컬러 프레임 버퍼에 씁니다. 큐브와 구의 화려한 패치 워크는 RGBA 색상으로 인코딩 된 실제 페이지 인덱스입니다. 그런 다음이 프리 패스 렌더링은 메인 메모리로 읽혀 Page Resolver지고 페이지 인덱스를 디코딩하고으로 새 요청을 발생시키기 위해에 의해 처리됩니다 Page Provider.

피드백 프리 패스 후 장면은 VT 조회 쉐이더로 정상적으로 렌더링 될 수 있습니다. 그러나 새 페이지 요청이 완료되기를 기다리지 않으면 동기 파일 IO를 단순히 차단하기 때문에 끔찍합니다. 요청은 비동기 적이며 최종 뷰가 렌더링 될 때까지 준비되거나 준비되지 않을 수 있습니다. 그것들이 준비되어 있고 달콤하지만 그렇지 않은 경우 항상 캐시에 저해상도 밉맵의 잠긴 페이지를 폴백으로 유지하므로 사용할 텍스처 데이터가 있지만 흐리게 처리됩니다.

체크 아웃 할 가치가있는 기타 리소스

VT는 여전히 컴퓨터 그래픽에서 다소 인기있는 주제이므로 사용할 수있는 좋은 자료가 많이 있으므로 더 많이 찾을 수 있어야합니다. 이 답변에 추가 할 수있는 것이 있으면 언제든지 문의하십시오. 나는 주제에 대해 조금 녹슬 었습니다. 지난 한 해 동안 그것에 대해 많이 읽지 않았지만 메모리가 물건을 다시 방문하는 것이 좋습니다. :)


훌륭한 답변 감사합니다. 나는 이것이 일반적으로 눈살을 찌푸 리다는 것을 알고 있지만, 나는 여러 가지 문제가 있으므로 대부분 사물을 훑어 봅니다. 미래에 대한 주제에 대한 직관적 인 개요를 얻기 위해 )-어쨌든 가능한 경우 프로세스 자체를 설명하는 의사 코드 예제를 게시 할 수 있습니까?
Llamageddon

1
@Llamageddon, 그것은 여전히 ​​다이어그램을 가지고 있기 때문에 발생합니다.) 의사 코드는 실제 코드가 약간 있기 때문에 제공하기가 조금 어려울 것입니다. 그러나 확장 된 답변이 기술에 대한 일반적인 아이디어를 제공하는 데 도움이되기를 바랍니다.
glampert

3
대부분의 최신 하드웨어는 이제 프로그래밍 가능한 페이지 테이블을 표시하므로 리디렉션 텍스처가 필요하지 않습니다. 이것은 directx12 예약 된 자원 , 즉 directx11 타일 ​​자원 또는 opengl 스파 스 텍스처를 통해 제공 됩니다.
MooseBoys 2019

1
@Llamageddon, 피드백 프리 패스는 가능한 한 많은 컴퓨팅과 메모리를 절약하기 위해 저해상도에서 수행 할 수 있습니다. 페이지의 픽셀은 일반적으로 반복되므로 (내 데모에서 큰 색의 사각형을 볼 수 있습니다). 결국 페이지가 보이지 않을 수도 있지만, 시스템이 항상 캐시에서 사용할 수있는 전체 VT의 최소 밉맵을 유지해야하기 때문에 시각적으로 큰 영향을 미치지는 않을 것입니다. 내가 링크 한 두 번째 논문에는 부록의 모든 셰이더 예제가 있으며, 내 프로젝트의 저장소를 참조 할 수도 있습니다.
glampert

1
@glampert Ahh, 알겠습니다. 말이 되네요 여전히 투명 용지를 처리 ​​할 수있는 옵션이 많이 있다고 생각합니다. 페이지 ID 패스에서 디더링을 수행하거나 (투명한 레이어 수가 많지 않은 경우 히스토그램에서 모든 페이지를 볼 수 있음) k- 버퍼 접근 방식 을 사용하거나 객체가 카메라 (피드백 패스로 렌더링하는 것과 반대).
Nathan Reed

11

가상 텍스처링은 텍스처 아틀라스의 논리적 극단입니다.


텍스처 아틀라스는 그 안에 개별 메시에 대한 텍스처를 포함하는 하나의 거대한 텍스처입니다.

텍스처 아틀라스 예제

텍스쳐 아틀라스는 텍스처 변경으로 인해 GPU에서 전체 파이프 라인 플러시가 발생하기 때문에 대중화되었습니다. 메시를 만들 때 UV는 압축 / 시프 팅되어 전체 텍스처 아틀라스의 올바른 '부분'을 나타냅니다.

주석에서 @ nathan-reed가 언급했듯이 텍스처 아틀라스의 주요 단점 중 하나는 반복, 클램프, 테두리 등과 같은 랩 모드를 잃는 것입니다. 또한 텍스처에 테두리가 충분하지 않으면 실수로 실수로 할 수 있습니다 필터링 할 때 인접한 텍스처에서 샘플링합니다. 이것은 출혈 인공물로 이어질 수 있습니다.

Texture Atlases에는 크기라는 큰 제한이 있습니다. 그래픽 API는 텍스처의 크기에 대한 소프트 제한을 설정합니다. 즉, 그래픽 메모리는 너무 큽니다. 따라서 v-ram의 크기에 따라 질감 크기에 대한 제한도 있습니다. 가상 텍스처는 가상 메모리 에서 개념을 빌려이 문제를 해결합니다 .

가상 텍스처는 대부분의 장면에서 모든 텍스처의 작은 부분 만 볼 수 있다는 사실을 이용합니다. 따라서 텍스처의 하위 집합 만 vram에 있어야합니다. 나머지는 기본 RAM 또는 디스크에있을 수 있습니다.

그것을 구현하는 몇 가지 방법이 있지만, 나는 Sean Barrett이 그의 GDC talk 에서 설명한 구현을 설명 할 것이다 . (저는 시청하는 것이 좋습니다)

가상 텍스처, 물리적 텍스처 및 조회 테이블의 세 가지 주요 요소가 있습니다.

가상 텍스처

가상 텍스처는 모든 것에 맞도록 충분한 vram을 가지고 있다면 이론적 인 메가 아틀라스를 나타냅니다. 실제로 메모리 어디에도 존재하지 않습니다. 실제 텍스처는 실제로 vram에있는 픽셀 데이터를 나타냅니다. 조회 테이블은 둘 사이의 매핑입니다. 편의상 세 요소를 모두 같은 크기의 타일 또는 페이지로 나눕니다.

룩업 테이블은 실제 텍스처에서 타일의 왼쪽 상단 모서리 위치를 저장합니다. 따라서 전체 가상 텍스처에 UV가 주어지면 실제 텍스처에 해당하는 UV를 어떻게 얻습니까?

먼저 실제 텍스처 내에서 페이지의 위치를 ​​찾아야합니다. 그런 다음 페이지 내에서 UV의 위치를 ​​계산해야합니다. 마지막으로이 두 오프셋을 더하여 물리적 텍스처 내 UV 위치를 얻을 수 있습니다

float2 pageLocInPhysicalTex = ...
float2 inPageLocation = ...
float2 physicalTexUV = pageLocationInPhysicalTex + inPageLocation;


pageLocInPhysicalTex 계산

룩업 테이블을 가상 텍스처의 타일 수와 동일한 크기로 만들면 가장 가까운 이웃 샘플링으로 룩업 테이블을 샘플링하면 실제 텍스처 내에서 페이지의 왼쪽 상단 모서리 위치를 얻을 수 있습니다.

float2 pageLocInPhysicalTex = lookupTable.Sample(virtTexUV, nearestNeighborSampler);


PageLocation에서 계산

inPageLocation은 전체 텍스처의 왼쪽 위가 아니라 페이지 왼쪽 위를 기준으로하는 UV 좌표입니다.

이를 계산하는 한 가지 방법은 페이지 왼쪽 상단의 UV를 빼고 페이지 크기로 조정하는 것입니다. 그러나 이것은 약간의 수학입니다. 대신, IEEE 부동 소수점이 어떻게 표현되는지를 활용할 수 있습니다. IEEE 부동 소수점은 일련의 기수 2 분수로 숫자의 소수 부분을 저장합니다.

여기에 이미지 설명을 입력하십시오

이 예에서 숫자는 다음과 같습니다.

number = 0 + (1/2) + (1/8) + (1/16) = 0.6875

이제 가상 텍스처의 단순화 된 버전을 살펴 보겠습니다.

간단한 가상 질감

1/2 비트는 텍스처의 왼쪽 절반에 있는지 아니면 오른쪽에 있는지 알려줍니다. 1/4 비트는 우리가 반의 1/4을 알려줍니다.이 예에서는 텍스처가 16 또는 4로 나뉘어져 있기 때문에 처음 두 비트는 우리가 어떤 페이지에 있는지 알려줍니다. 비트는 페이지 내의 위치를 ​​알려줍니다.

exp2 ()로 float를 이동시키고 fract ()로 제거하여 나머지 비트를 얻을 수 있습니다.

float2 inPageLocation = virtTexUV * exp2(sqrt(numTiles));
inPageLocation = fract(inPageLocation);

여기서 numTiles는 텍스처의 측면 당 타일 수를 제공하는 int2입니다. 이 예에서는 (4, 4)입니다.

녹색 점에 대한 inPageLocation을 계산해 봅시다. (x, y) = (0.6875, 0.375)

inPageLocation = float2(0.6875, 0.375) * exp2(sqrt(int2(4, 4));
               = float2(0.6875, 0.375) * int2(2, 2);
               = float2(1.375, 0.75);

inPageLocation = fract(float2(1.375, 0.75));
               = float2(0.375, 0.75);

우리가 끝나기 전에 할 마지막 일. 현재 inPageLocation은 가상 텍스처 '공간'의 UV 좌표입니다. 그러나 물리적 텍스처 '공간'에는 UV 좌표가 필요합니다. 이를 위해 가상 텍스처 크기와 실제 텍스처 크기의 비율로 PagePage에서 크기를 조정하면됩니다.

inPageLocation *= physicalTextureSize / virtualTextureSize;



완성 된 기능은 다음과 같습니다.

float2 CalculatePhysicalTexUV(float2 virtTexUV, Texture2D<float2> lookupTable, uint2 physicalTexSize, uint2 virtualTexSize, uint2 numTiles) {
    float2 pageLocInPhysicalTex = lookupTable.Sample(virtTexUV, nearestNeighborSampler);

    float2 inPageLocation = virtTexUV * exp2(sqrt(numTiles));
    inPageLocation = fract(inPageLocation);
    inPageLocation *= physicalTexSize / virtualTexSize;

    return pageLocInPhysicalTex + inPageLocation;
}

나는 내가 가장 잘 IDTECH 5의로 알려진 가상 텍스처링, 말하는 겁니다, 아니에요 MegaTexture의 기술. 이것이것도 참조하십시오 . 나는 많은 현대 엔진의 렌더링 파이프 라인 개요와 섀도 맵에 대해 비슷한 접근 방식을 사용하는 몇 가지 논문에서 언급 한 것을 보았습니다. 텍스처 아틀라스와 많은 공통점이 있습니다. 그렇습니다. 어쨌든 그것들을 사용하지만 텍스처 아틀라스와 혼동하지 않습니다.
Llamageddon

아 링크 주셔서 감사합니다. 질문에 추가 할 수 있습니까? 이에 따라 답변을 업데이트하겠습니다.
RichieSams

3
단순한 텍스처 아틀라스 (가상 텍스처 아님)의 주요 단점은 반복 및 클램프와 같은 랩 모드를 잃어 버리고, 부동 소수점 정밀도가 아닌 필터링 / 밉 매핑으로 인해 블리딩이 발생한다는 것입니다. 플로팅 정밀도가 일반 (가상이 아닌) 텍스처의 문제가되는 것을보고 놀랐습니다. 16K 텍스처 (현재 API가 허용하는 최대 값)조차도 부동 소수점 정밀도를 실제로 변형시킬만큼 크지 않습니다.
Nathan Reed

@ RichieSams Btw, 나는 다른 질문에 당신의 대답이 좋은 것이라고 생각합니다. Q & A 포스트를 작성해야합니다.
Llamageddon

흠, 이것이 밉 레벨과 어떻게 작동하는지 실제로 이해하지는 못하지만 상당히 잘 설명되어 있습니다. 나는 그것을 이해하면서 나의 특정한 문제를 적을 수 있었으면 좋겠지 만, 그것은 다소 나를
피하기 위해
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.