정점이 24 개 미만인 큐브를 구성 할 수 있습니까?


14

Minecraft와 같은 큐브 기반 세계가 있으며 정점 수가 24 개 미만인 큐브를 구성하여 메모리 사용을 줄일 수있는 방법이 있는지 궁금합니다.

두 가지 이유로 나에게는 불가능한 것 같습니다. 법선이 제대로 나오지 않고 면당 텍스처가 작동하지 않습니다.

이 경우입니까 아니면 내가 틀렸습니까? 어쩌면 도움이 될만한 새로운 DX11 기술이 있습니까?

편집 : 명확히하기 위해 2 가지 요구 사항이 있습니다. 적절한 조명을 수행하기 위해 각 큐브 얼굴에 표면 법선이 필요하며 각 큐브 얼굴에 대해 텍스처 배열의 다른 인덱스를 처리하는 방법이 필요합니다


1
당신은 감소 하시겠습니까 그래픽 카드 메모리 사용 또는 RAM 사용량을 ?
doppelgreener

1
정점 데이터는 현재 RAM과 GPU에 저장되어 있으므로 축소하면 둘 다 줄일 수 있습니다.
Telanor

답변:


9

면당 법선 만 필요하고면의 texcoord가 엄격하게 0/0, 0/1, 1/0, 1/1 (또는 레이아웃에 적합) 인 경우 8 개의 정점으로 큐브를 구성 할 수 있습니다 30 (다시 시작한 스트립) 또는 36 (목록) 인덱스 중 하나입니다. 정점 셰이더의 SV_VertexID를 기반으로하는 상수 배열 조회를 사용하여 법선과 텍스 코치를 가져옵니다.

이렇게하면 정점 버퍼에 texcoord 또는 법선을 포함 할 필요가 없으므로 훨씬 더 많은 메모리를 절약 할 수 있습니다.

더 나아가서 큐브 당 24 버트로 계속 갈 수 있지만 인스턴스를 사용할 수도 있습니다. 각 큐브는 정점 버퍼 (1x1x1)에서 고정 크기가되며 인스턴스 별 데이터로 스케일링 계수와 위치 (큐브가 회전하지 않는 것으로 가정)를 갖게됩니다. 비 회전의 경우 일회성 비용은 24 버트이지만 각 큐브는 완전히 지정하기 위해 6 개의 플로트가 필요합니다. 회전하는 경우 16 개의 부동을보고 있지만 상당한 절약입니다 (이 경우 매트릭스 변환에서 CPU 측 병목 현상이 발생할 가능성이 높습니다)-비 회전 케이스는 즉시 매트릭스를 구성합니다 정점 셰이더-정점마다 수행 되더라도 너무 멍청해서 걱정할 필요가 없습니다.)

면별 텍스처의 경우 텍스처 배열을 사용하십시오. 물론 배열의 각 텍스처가 동일한 크기인지 확인해야하며 배열 자체를 변경 해야하는 경우 여전히 현재 배치를 중단해야하지만 그렇지 않으면 제대로 작동합니다. 각면에 사용할 배열 슬라이스를 정의하는 정점 정의에 세 번째 texcoord를 추가하십시오.

GS가 필요하지 않으며 지오메트리 쉐이더 스테이지를 활성화하면 자체 오버 헤드가 추가되므로 GS를 사용하는 것보다 빠르게 실행해야합니다.

나는이 방법을 사용하여 많은 큐브를 그리는 엔진에 벤치 마크 코드를 작성했으며 프로세스를 최적화하기 위해 다른 작업을 수행하지 않고 60fps를 지우면서 60fps를 지우면서 쉽게 씹을 수 있습니다. . 분명히 나는 ​​그것들을 조명하거나 텍스처링하지는 않지만, 알파 블렌딩을 활성화하고, 뒷면 컬링을 비활성화하고, 전체적으로 "최적화를 위해 다른 것을하지 않는"부분과 균형을 유지하므로, 당신은 종류의 합리적인 아이디어를 제공해야합니다 이 방법으로 볼 수있는 야구장.


1
나는 전에 인스턴스를 사용하고 있었고 40k 큐브 미만에서 훌륭하게 작동합니다. 그러나 나는 적어도 256k 큐브를 가지고 있으며 인스턴스화도 처리하지 못했습니다. SV_VertexID를 조회와 함께 사용하면 매우 유망한 것으로 들립니다.
Telanor

인스턴스 별 버퍼는 얼마나 되었습니까? 그것들을 모두 거대한 버퍼에 넣으려고하면 GPU를 질식시킬 수 있습니다. 나는 일반적으로 인스턴스 당 버퍼를 64k 객체 (필요한 경우 그리기 호출을 나누기)에 충분한 공간에 유지하고 폐기 / 덮어 쓰기 패턴을 사용하고 중간 배열에서 복사하는 대신 매핑 된 포인터에 직접 씁니다. 매우 잘 작동합니다. .
Maximus Minimus

또한지도 수를 낮게 유지하는 것이 중요합니다. 하나의 큐브 / 맵 해제 40k 시간 맵 / 쓰기는 한 번만 맵 / 쓰기 40k 큐브 / 맵 해제보다 속도가 훨씬 느립니다. 전자를하고 있다면 후자로 바꾸어보십시오.
Maximus Minimus

15

나는 당신이 할 수있는 주요 최적화가 모든 큐브가 실제로 24 개의 정점을 모두 필요로하지는 않는다는 사실에 근거한다고 생각합니다 . 실제로, 24 개의 정점이 필요한 유일한 큐브는 공중에 떠있는 큐브입니다.

일반적으로 air와 접촉하는면의 쿼드 만 생성 합니다. 즉, 두 개의 큐브가 서로 닿으면 접촉하는 얼굴에 꼭짓점을 생성 할 필요가 없습니다.

아래 이미지는이 개념을 보여 주지만 이해하기 쉽게 2D로 보여줍니다. 이미지에는 11 개의 점유 된 블록 (채워진 회색 원으로 표시)이 있으며 일반적으로 4 x ​​11 = 44 개의 모서리 (입방체가 아닌 정사각형이므로 4)가 필요합니다. 그러나 당신이 볼 수 있듯이, 당신은 가장자리가 빈 사각형과 접촉 할 때 가장자리를 그릴 필요가 있습니다.이 경우에는 8 개의 가장자리입니다.

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

2D에서 이러한 간단한 예가 44 개의 가장자리를 8 개의 가장자리로 줄 였다면 큰 3D 세계에서 이득을 상상해보십시오.

이것이 OpenGL을 목표로하고 있음에도 불구 하고이 기사 에서 설명하는 접근 방식 입니다. 그래도 개념은 매우 보편적이어야합니다.

또한 지오메트리 쉐이더 를 사용 하여 GPU에서 즉시 정점을 생성하여 메모리에 저장할 필요가 없지만 경험이 없거나 큰 성능을 알지 못합니다. 세계.


1
매우 흥미로운 기사. 나는 이미 가장자리 최적화를하고 있는데, 그것은 확실히 많은 도움이됩니다. 지오메트리 쉐이더에 시도해보고 그것이 효과가 있는지 알아 보겠습니다.
Telanor

기하 셰이더와 교차 곱을 사용하여 법선을 계산합니까? 나는 평평한 표면을위한 별도의 프로그램을 만드는 것과 같이 그것을 사용하려고 생각했습니다 (질감에 관심이 없습니다).
dreta

@dreta뿐만 아니라 큐브 중심을 포인트 목록으로 제출하는 지점으로 이동하면 모든 정점이 GS에 의해 방출됩니다. 어쩌면 생각하지는 않았지만 셰이더가 실제로 필요한 얼굴 만 생성하도록 주변 정보를 포인트로 인코딩 할 수 있습니다.
David Gouveia

원하는 성능이라면 지오메트리 쉐이더를 사용하지 마십시오. 그들은 파이프 라인을 완전히 망칩니다. GPU에서 지오메트리를 생성하려면 컴퓨팅 셰이더 또는 openCL을 사용하십시오
Robert Fraser
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.