복셀 렌더링의 경우 사전 제작 된 VBO 또는 지오메트리 쉐이더가 더 효율적입니까?


26

상당히 정적 인 복셀 배열이 있다면 더 효율적인 것입니다 .CPU를 사용하여 VBO를 미리 생성하여 복셀면을 렌더링하거나 (현재 행진 큐브와 같은 고급 렌더링 형식을 무시하고) GPU에서 지오메트리 쉐이더를 사용하여 즉석에서 얼굴?

나는 복셀을 업데이트하는 것에 대해 걱정하지 않지만 VBO를 다시 만들 필요가 없기 때문에 GPU 버전의 이점입니다. 또한 GS 접근법은 조금 더 현대적입니다. :)

반면에, 현대 GPU에서 GS가 실제로 래스터 화 파이프 라인과 어떻게 작동하는지에 대한 세부 사항은 살펴 보지 않았습니다. 정점을 일종의 스트림 캐시로 출력합니까 아니면 정점을 사이에 일반 GPU 메모리에 기록합니까? 후자의 경우 즉시 생성은 내가 추측하는 나머지 GPU 작업에서 사용 가능한 대역폭과 처리 능력을 감소시킬 수 있으며 CPU에서 수행하는 것이 더 유리합니다.

답변:


9

복셀에 의해 실제로 다각형을 사용하여 렌더링되는 블록의 세계를 의미하는 마인 크래프트 유형 장면을 생각하고 있습니다.

지오메트리 쉐이더를 사용하는 경우 복셀 당 정확히 세 개의면 (또는 무엇이든)을 피하는 것이 어렵습니다.

텍스처가 동일한 인접한 블록이 많이있는 경우 텍스처 타일링을 사용하여 VBO 방식에서 (축소 된) 스트립에 삼각형이 훨씬 적습니다. 내 말은, 잔디 복셀의 멋진 6x6 면적의 커다란 평면이 있다면, 전체 상단을 64 개가 아닌 2 개의 삼각형으로 그릴 수 있습니다.

GS 접근 방식을 사용하면 VBO 접근 방식을 사용하여 매우 간단한 인접 복셀로 막힌 사소한 얼굴 컬링을 수행 할 수 없습니다.

GS 접근법을 시도하지는 않았지만 반복되는 인접한 타일을 결합한 VBO 접근법은 매우 효과적이라고 말할 수 있습니다. 정점을 반복하는 것보다 요소 인덱스를 엉망으로 만드는 것이 훨씬 느리다는 것을 알았습니다. 월드를 멋진 작은 큐브로 분할하면 일반적으로 버텍스 당 구성 요소 당 하나의 바이트 만 사용하고 텍스처 정보와 법선 (축 정렬 큐브의 얼굴에는 가능한 법선이 3 개만 있음) 등을 4 바이트로 묶을 수 있습니다. 정점 당 4 바이트로 멋지고 빠릅니다.

나는 6 개의 얼굴 각각에 대해 별도의 VBO를 사용했습니다. 최대 3 개의 얼굴 만 분명히 그려야합니다. 이것은 마인 크래프트 스타일 복셀의 상단 부분에 일반적으로 사용되는 다양한 텍스처링에 잘 맞습니다. 각각의 세트에 대해 정상 및 그 때문에 균일하기 때문입니다.

GL_REPEAT수평 축이 있는 아틀라스에서 수직 타일 픽스 맵을 사용하고 동일한 아틀라스에 픽스 맵의 90도 회전 버전을 사용하면 동일한 호출에서 동일한 VBO를 사용하여 분명히 다른 블록을 대량으로 그릴 수 있습니다. 6x6 잔디 영역 예에서는 아틀라스의 한 차원에서만 반복하므로 12 개의 삼각형으로 나눕니다.

나는 주로 통합 그래픽 칩과 모바일의 매우 낮은 엔드에서이 작업을 수행 해왔다. GS는 언젠가는 꿈을 꿀 수있는 것이다.


3
복셀 당 최대 3 개의 면만 그려야하지만 시점에 따라 각 복셀마다 다른면을 그려야하므로 최적화가 쉽지 않습니까? 사전 제작 된 VBO에는 둘 이상의 복셀이 포함됩니다. 시점이 복셀 사이에 있으면 한쪽의 동쪽과 다른 쪽의 서쪽이 보입니다. 이것이 도움이 될 수있는 유일한 방법은 실제 후면을 사소하게 잡아 당기는 것입니다. 그러나 최악의 경우 여전히 복셀 그룹에서 5/6면을 렌더링합니다. 관측점이 VBO의 축 제한을 벗어나 면 3 면만 렌더링하면됩니다.
Bjorn Wesen

Bjorn에서 발견하십시오. (하지만 필요에 따라 블록 VBOs을 만들고 내가 만든 것을 다시 생각하고 때 오히려 항상 VBOs에서 전 세계를하는 것보다 카메라의 이동, 나는이 선택을 할 수있는 자연의 시간이되도록)

10

인스턴스화 된 배열을 사용하는 세 번째 옵션은 어떻습니까? 기본적으로 단일 드로우 콜로 많은 상자 (단순 8 버텍스 큐브로 만든)를 그려서 voxel-data VBO의 인스턴스 속성으로 위치 및 기타 데이터를 소싱합니다 ( glVertexAttribDivisorOpenGL에서 사용) . DX도 마찬가지입니다). 응용 프로그램 코드 (비 셰이더)는 상당히 유사해야하지만 지오메트리 셰이더 접근 방식보다 빠를 수 있습니다. 지오메트리 셰이더는 느리게 명성을 얻었으므로 기억합니다. 2.1 하드웨어에서.

그러나 어쨌든 지오메트리 셰이더 또는 인스턴스 배열은 특히 보셀 데이터가 변경 될 때 CPU 내장 보셀 지오메트리보다 더 적합해야합니다. 변환 피드백 (DX의 스트림 출력?)과 함께 GPU 기반의 우수한 컬링 기술을 설정할 수 있습니다.


네, 이것이이 문제에 대한 최선의 해결책입니다. 왜 나에게 발생하지 않았습니까? :)
Notabene

몇 가지 실험을 한 후에는 구운 지오메트리가 인스 턴싱을 크게 뛰어 넘습니다. 그래도 지오메트리 쉐이더를 시도하지 않았습니다.
Jari Komppa

@JariKomppa 구운 지오메트리의 의미에 대해 자세히 설명 할 수 있습니까?
Steven Lu

인스턴스가 사전 변환되고 단일 메시로 복사되었습니다. 백 큐브 또는 그 밖의 것을 나타내는 하나의 메쉬를 갖는 것과 같습니다.
Jari Komppa 2012

@JariKomppa 메쉬를 만드는 것이 훨씬 빠른 동일한 결과를 보았습니다. 그러나 gtx 680에서 인스 턴싱 옵션은 훨씬 빠르고 이상하게 작동하는 것 같습니다.
Levi H

1

지오메트리 셰이더 버전이 훨씬 나아졌습니다. 점 vbo와 구성 상자 만 입력 할 수 있습니다 (입력 점, 출력 삼각형 스트림). 속도가 빠르며 (쉐이더 모델 5 eq. DX11에서 테셀레이션 단위를 사용하는 경우에도 더 빠름) 대역폭을 크게 줄이면 멋지고 깨끗한 솔루션이됩니다.

GS 소개 버텍스 쉐이더와 픽셀 쉐이더 사이에 위치하며 출력 된 버텍스 (프리미티브) 스트림을 수정합니다. 정점 셰이더는 정점에서만 작동하지만 지오메트리 셰이더는 전체 기본 체에서 작동합니다. 이 스트림의 출력은 픽셀 셰이더에만 적용되며 (물론 코스 전에 래스터 화됩니다.) 저장할 수있는 방법이 없습니다. (어쩌면 질감을 렌더링하고 파싱하는 미친 렌더링에 의해 ... 아마도 간단한 가능성은 없습니다)

퍼포먼스 노트 : 지오메트리 쉐이더의 모든 것에 적용 할 수 있어야하고 정점 쉐이더를 건너 뛰어야합니다 (데이터 만 전달). 그러나 최선의 방법은 아닙니다. 버텍스 쉐이더에서 가능한 대부분의 변환을 수행하고 지오메트리 쉐이더 프로그램을 최소화하는 것이 좋습니다. 사이클 제작에 필요한 경우 (예를 들어 박스 생성 등) 사용하는 것을 두려워하지 마십시오. 컴파일러가 자동으로 언 롤링합니다.


2
지오메트리 및 / 또는 정점 셰이더에서 인접 복셀을 확인하고 정점을 삭제하거나 폐쇄 된면을 건너 뛰는 것이 좋습니다. 그렇지 않으면 GS 솔루션이 대신 사용 된 대역폭을 증가시킵니다.
Tamschi

Bandwith는 (내 경험상) 큰 문제는 아니지만 물론 물론 사실입니다. 그리고 당신은 GS의 다른 프리미티브를 검색 할 수 없습니다 (나는 알고 있습니다 :)).
Notabene

@Tamschi : 그렇습니다.이 질문을 쓴 직후에이 문제가 발생했습니다 .. CPU 버전의 경우, 고형물의 중간에있는 복셀은 억제되지만, 차별화 ..
Bjorn Wesen

1
버텍스 버퍼를 셰이더에서 isamplerBuffer 또는 usamplerBuffer 유니폼에 바인딩 한 다음 texture (name_of_uniform, index)로 조회를 수행 할 수 있습니다. 또 다른 옵션은 버퍼를 균일 한 배열에 바인딩하는 것입니다. 어느 버텍스 형식을 사용하든 더 자유로울 수 있습니다.
Tamschi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.