큰 정점 버퍼 대 다중 드로우 호출


14

방금 OpenGL을 시작했으며 2D 게임을 만드는 데 사용하려고합니다. 이 게임에서는 다양한 색의 육각형으로 구성된 육각형 격자가 있습니다. 초보자 OpenGL 프로그래머로서이 그리드를 그리는 두 가지 방법이 있습니다.

  1. 단일 육각형의 데이터와 함께 정점 버퍼를 사용한 다음 균일 한 오프셋 값을 사용하고 CPU에서 반복하여 그리드가있을 때까지 동일한 프로그램을 여러 번 그립니다.
  2. 한 번의 호출로 모든 육각형을 그리는 매우 큰 사전 계산 된 정점 버퍼를 만듭니다.

가장 효율적인 방법은 무엇입니까? 더 좋은 방법이 있습니까?


미리 계산 된 정점 버퍼는 화면을 지나서 하나의 육각형만큼만 확장하면되며, 전체 육각형이 될 때까지 부드럽게 스크롤 한 다음 다시 뒤 틀리면 위조 될 수 있습니다.이 시나리오의 색상은 GPU의 2D 텍스처를 정점 셰이더에서 읽은 다음 프래그먼트 셰이더에 평면 보간합니다.
MickLH

패스는 일반적으로 하나의 렌더 작업이 이전 작업의 결과에 의존하는 상황을 나타냅니다. 이 질문에서 요구하는 것은 실제로 단일 패스 내에서 드로우 콜 수를 줄이는 것과 관련이 있습니다. 나는 현학적 소리로 들리 겠지만 그렇지 않으면 멀티 패스 알고리즘은 많은 의미를하지 않습니다 차이를 이해하는 것이 매우 중요합니다)
안돈 M. 콜맨

@ AndonM.Colman Hmm, 그래픽 용어에 익숙하지 않습니다. 이 경우 어떻게 설명해야합니까? 여러 셰이더 / 프로그램 호출?
Alexis King

순서 의존성이 없기 때문에 이것이 단일 패스 알고리즘임을 즉시 알 수 있습니다. 이 육각형을 임의의 순서로 그릴 수 있으며 여전히 동일한 결과를 얻을 수 있습니다. OpenGL을 렌더링하는 데 필요한 데이터를 제공하기 위해 여러 번의 그리기 호출 이 필요할 수 있지만 OpenGL은 종속성이 없기 때문에 효과적으로 병렬로 그릴 수 있습니다. 그것이라면 멀티 패스 , 다음이 그려되기 전에 육각 B 육각 A의 결과를해야 할 수 있습니다, 또는 당신은 같은 육각형 여러 번을 그리고 결과를 결합해야 할 수도 있습니다.
Andon M. Coleman

답변:


9

그러한 그리드를 만드는 몇 가지 방법이 있습니다.

가장 효율적인 방법은 인스 턴싱입니다. 이렇게하면 VBO에서 육각형을 한 번만 만들고이를 수백, 천 또는 백만 번 렌더링합니다. 포인트 1에서 언급 한 것처럼 유니폼이있는 셰이더를 사용하여 수동으로 수행 할 수 있지만 내장 된 OpenGL 기능도 있습니다. 이를 위해 glDrawElementsInstanced를 살펴 보십시오 .

인스턴스화 된 객체를 일정량 이상 그리는 경우 인스턴스화는 다른 방법보다 빠릅니다. 예를 들어 1 개의 큰 VBO를 사용하면 300을 그리는 것이 더 빠를 수 있지만 인스턴스 렌더링을 사용하면 2 백만을 그리는 것이 더 빠를 수 있습니다.

인스턴스 렌더링을 사용하는 경우 Attribute Divisors를 사용하여 객체 별 데이터를 보낼 수 있습니다 . 귀하의 경우 위치와 색상을 보내려고합니다.

인스턴스 렌더링에 대한 유용한 자습서 : click

실제로 가장 좋은 방법은 두 방법을 모두 시도하고 1 프레임을 그리는 데 걸리는 시간 (밀리 초)을 확인하는 것입니다. 이 방법으로 두 가지 방법을 모두 배울 수 있으며 항상 좋습니다.

또한 인스턴스 렌더링은 최신 OpenGL 기능이며이를 사용하려면 셰이더를 사용해야합니다. 그러나 처음부터 올바른 방법을 배우는 것이 가장 좋습니다.


2
인스 턴싱이 반드시 가장 효율적인 것은 아닙니다. 많은 구현에서 프로파일을 보았을 때, 인스턴스화 지원은 적합성을 고려했지만 많은 객체를 개별적으로 그리는 것보다 느립니다 (실제로 드라이버에서 루프를 제대로 구현하지 않았을 가능성이 높습니다). 옵션이며 좋은 방법이지만 "가장 효율적"이라는 가정을하기 전에 대상 OS / 하드웨어를 프로파일 링하고 테스트하는 데 신중해야합니다.
Sean Middleditch

동의했다. 예를 들어 Windows / Linux 및 Ati / nVidia에서 다른 성능을 보았습니다. 추가해 주셔서 감사합니다.
Basaa

1
사실로. 단일 vbo 내에서 여러 개의 결합 된 메쉬를 그리는 경우 (같은 공간을 공유 함). 인스 턴싱이 더 빠를 수는 없습니다. 인스턴스화의 문제점은 정점이 교차 계산 된 교차 인스턴스가 아니라는 것입니다. gpu / cpu / gpu sync / drawcall 만 제거합니다. 따라서 하드웨어 인스턴스를 사용하여 1000 개의 구를 그리는 것보다 1000 개의 구를 포함하는 하나의 정점 버퍼를 그리는 것이 더 빠릅니다. (절두체 컬링 / 물체 거리 세부 사항 최적화가 필요 없음)
Jeroen van Langen

3

방법 1은 코딩하기가 더 간단하고 한 번에 너무 많은 육각형이없는 한 괜찮습니다. OpenGL을 처음 사용하기 때문에 한 번에 플레이트에 너무 많은 복잡성을 피하기 위해 이것을 고수하고 싶을 수도 있습니다.

한 번에 많은 수의 육각형 (예 : 수백 또는 천 개 이상)이있는 경우 너무 많은 개별 드로우의 CPU 오버 헤드를 피하기 위해 오버 헤드가 낮은 방법이 필요합니다. 방법 2는 이것을 위해 작동하거나 더 나은 방법으로 인스턴스화를 사용합니다. 인스턴스 2가 방법 2보다 빠르거나 더 나쁘지는 않을 것으로 예상됩니다. 모든 인스턴스에 대해 (훨씬 큰) 정점 데이터 버퍼 대신 인스턴스 별 데이터 버퍼 만 업데이트하면되기 때문입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.