2010-06-02 3 views
40

gl [Multi] DrawElements 등으로 그려진 OpenGL 정점의 인덱스 배열을 사용할 때를 명확하게 생각하려고 할 때 대 gl [Multi로 그려진 정점의 연속 배열을 단순히 사용해야하는 경우 ] 그리기 배열.언제 OpenGL 정점의 인덱스 배열을 사용해야합니까?

(는 업데이트 :. 하나는 항상 인덱스 정점을 사용하는 것이 내가 가진 응답에 합의는)

나는 앞뒤로이 문제에 대한 여러 번 갔다, 그래서 나는 윤곽을거야 내 현재의 이해, 희망에 누군가가 나에게 이제는 마침내 더 많거나 적은 정확하다고 말할 수 있습니다. 그렇지 않으면 남은 오해가 어디에 있는지를 지적 할 수 있습니다. 특히 세 가지 결론을 굵게 표시했습니다. 잘못 되었다면 수정하십시오.

하나의 간단한 경우는 내 지오메트리가 곡면으로 구성된 메쉬로 구성된 경우입니다. 이 경우 메쉬 중간의 정점은 정점을 사용하는 모든 삼각형에 대해 동일한 속성 (위치, 표준, 색상, 텍스처 좌표 등)을 갖습니다.

이 그렇게 결론 날 리드 : 몇 솔기 지오메트리를 들어

1. 인덱스 배열은 큰 승리입니다.

따르 규칙 1은 항상 제외 : 모든 가장자리는 솔기를 대표하는 매우 '육중 한'지오메트리를 들어

, 인덱스 배열의 장점은 덜 분명하다. 간단한 큐브를 예로 들자면, 각 꼭지점은 3 개의 다른면에서 사용되지만, 그 사이에 꼭지점을 공유 할 수는 없습니다. 왜냐하면 단일 꼭지점의 경우 표면 법선 (색상 및 텍스처 좌표)는 각 얼굴마다 다를 수 있습니다. 따라서 우리는 배열에 여분의 정점 위치를 명시 적으로 도입해야하므로 동일한 위치가 다른 법선 등으로 여러 번 사용될 수 있습니다. 즉, 인덱스 배열의 사용이 적습니다.

0  1 
    o---o 
    |\ | 
    | \ | 
    | \| 
    o---o 
3  2 

(앞면 모든 인접면 사이의 이음매가면 사이에 공유 될 수있는 이러한 정점 중에보다 의미 때문에이 분리되어 고려 될 수있다)

: 큐브의 하나의 얼굴을 렌더링 할 때 GL_TRIANGLE_FAN (또는 _STRIP)를 사용하여 렌더링하는 경우, 다음 큐브의 각면 따라서 렌더링 할 수 있습니다 :

verts = [v0, v1, v2, v3] 
colors = [c0, c0, c0, c0] 
normal = [n0, n0, n0, n0] 

추가 인덱스 우리가이 문제를 단순화 할 수 없습니다. 이에서

나는 결론이 :

2. 다음 내가 인덱스 배열을 사용해서는 안됩니다, GL_TRIANGLE_STRIP 또는 _FAN을 사용하고 대신 항상 멀티 [GL 사용해야하는 경우, 모든 솔기 또는 대부분의 솔기를 지오메트리를 렌더링 ] 그리기 배열.

(업데이트 :)이 결과는이 결론이 잘못되었음을 나타냅니다.

: 인덱스 우리가 여기에 배열의 크기를 줄이기 위해 허용하지 않는 경우에도) 코멘트에서 논의

2 규칙의 유일한 예외는, 그들은 여전히 ​​때문에 다른 성능 이점 사용해야합니다 스트립이나 팬 대신에 GL_TRIANGLES를 사용할 때 각 큐브면이 두 개의 개별 삼각형으로 렌더링되기 때문에 꼭지점의 절반을 동일한 법선과 색상 등으로 두 번 다시 사용할 수 있습니다. 또, 동일한 단일 큐브 얼굴 : 정점 이후

verts = [v0, v1, v2, v2, v3, v0] 
normals = [n0, n0, n0, n0, n0, n0] 
colors = [c0, c0, c0, c0, c0, c0] 

및 일반 3 수레 각각 자주, 그리고 : 인덱스없이

0  1 
    o---o 
    |\ | 
    | \ | 
    | \| 
    o---o 
3  2 

, GL_TRIANGLES를 사용하여 배열은 같은 것을 할 것

verts = 6 * 3 floats = 18 floats 
normals = 6 * 3 floats = 18 floats 
colors = 6 * 3 bytes = 18 bytes 

= 36 floats and 18 bytes per cube face. 

(나는 다른 유형을 사용하는 경우 바이트 수는 변경 될 수 이해, 정확한 수치는 단지 illust위한 것입니다 : 색상은 종종에 대해, 각 큐브의 얼굴, 제공 3 바이트이며, . 배급) 지수와

, 우리는이 단순화 할 수 있습니다주는 작은 : 후자의 경우, 정점 0과 2 번 사용하는 방법

verts = [v0, v1, v2, v3]  (4 * 3 = 12 floats) 
normals = [n0, n0, n0, n0]  (4 * 3 = 12 floats) 
colors = [c0, c0, c0, c0]  (4 * 3 = 12 bytes) 
indices = [0, 1, 2, 2, 3, 0] (6 shorts) 

= 24 floats + 12 bytes, and maybe 6 shorts, per cube face. 

참조하지만, 단지 버텍스의 각 한 번 표현 , 법선 및 색상 배열. 모든 단일 기하학 모서리가 솔기가되는 극단적 인 경우에도 인덱스 사용에 대한 작은 승리처럼 들립니다.

이 그런 결론 날 리드 : GL_TRIANGLES를 사용하는 경우

3.

이 하나에도 항상 모든 솔기 지오메트리를 들어, 인덱스 배열을 사용해야합니다.

틀린 경우 제 결론을 굵게 수정하십시오. 이에서

+1

이 질문의 형식이 마음에 듭니다. – SimpleVar

답변

33

나는 결론을 그 다음 내가 인덱스 배열을 사용해서는 안됩니다, GL_TRIANGLE_STRIP 또는 _FAN을 사용하고 대신 항상 GL [멀티] DrawArrays를 사용해야 할 때 주로 모든 솔기 나 솔기, 지오메트리를 렌더링 할 때.

아니요, 그 이유는 아주 간단합니다.

귀하의 결론은 두 개의 삼각형으로 구성된 단일 쿼드를 분석 한 사실에 근거합니다. 삼각형 팬/스트립을 사용하여 그린이 두 삼각형은 인덱스 배열을 사용하여 단순화 할 수 없습니다.

그러나 큰 지형 기하학에 대해 생각해보십시오. 각 지형 블록은 삼각형 팬/스트립 프리미티브를 사용하여 쿼드로 그려집니다. 예를 들어

도면에서 각 삼각형 스트립 인접한 삼각형 스트립 모든 꼭지점 공통으로 갖고, 사용 지수 대신 각 삼각형 스트립 정점을 반복하는, 기하학적 정의를 압축 할 수있다.다른 하나는 단일 원시의 정점의 대부분을 공유 할 수 있습니다 때마다 인덱스를 사용하여


기본적으로, 그리기 프리미티브 (삼각형, 팬 및 스트립) 유용한이다.

정보를 공유하면 정보 전송 대역폭을 절약 할 수 있지만 이점이 아닙니다. 실제로 인덱스 배열 허용 :

  • 가 동일한 "개념적"정점에 속하는 정보의 동기화를 피하고 지정된 횟수를
  • 찾는 대신 여러 번 실행 한 꼭지점에 하나씩 동일한 셰이더 작업을 수행 할 수 있도록 각 정점 복제.
  • 또한 삼각형 스트립/팬과 인덱스를 결합하면 응용 프로그램이 인덱스 버퍼를 압축 할 수 있습니다. 스트립/팬 사양은 더 적은 인덱스 (삼각형은 각면에 항상 3 개의 인덱스가 필요합니다)가 필요하기 때문에 인덱스 버퍼를 압축 할 수 있습니다.

인덱스 배열은 다른 꼭지점과 연결된 모든 정보 (색상, 텍스처 좌표 등)를 꼭지점이 공유 할 수 없을 때마다 지정할 수 없습니다. 그냥 완성도를 위해서


는 형상 사양에 필요한 정보의 크기는 유일한 요소 느릅 나무는 최적의 렌더링 작업을 결정하지 않습니다.

기본 렌더링의 또 다른 기본 요소는 데이터의 캐시 로컬 리 제이션입니다. 잘못 지정된 지오메트리 데이터 (비 인터리브 버퍼 객체, 긴 삼각형 스트립 ...)는 많은 캐시 미스를 유발하여 그래픽 카드 성능을 저하시킵니다.

렌더링 작업을 최적화하려면 가장 높은 확률로 이전에 지정된 정점을 다시 사용하는 방식으로 정점 지정을 재정렬해야합니다. 이러한 방식으로 그래픽 카드 캐시 라인은 메모리에서 페치하지 않고 이전에 지정된 정점을 재사용 할 수 있습니다.

+2

+1하지만 인덱스를 사용하여 버텍스 캐시를 사용하는 것으로 추가 할 것입니다. 다양한 삼각형 사이에 공유 된 정점이 서로 가깝게 사용된다면 그래픽 카드는 인덱스 "i"를 변환 한 결과가 무엇인지 이미 알고 있으므로 캐시 된 대답을 다시 계산하지 않고 사용하게됩니다. 이것은 복잡한 버텍스 프로그램을 가지고있는 경우에 매우 유용합니다 ... 인덱스 된 스트립되지 않은 스트링과 인덱스되지 않은 스트립 사이의 정점 변환 작업의 양이 동일하다는 것을 의미합니다. 스트립되지 않은 경로가 더 최적화되어 스트립 된 것보다 나은 성능을 얻습니다. – Goz

+0

모든 것이 의미가 있습니다. 많은 의견을 보내 주셔서 감사합니다. 그러나 당신이 인용 한 결론 (2)은 특별히 "모든 솔기 또는 주로 솔기가있는 기하학을 렌더링 할 때"에만 적용된다고 말합니다. 당신이 보여준 큰 메쉬의 그림이 결론에 도달한다는 것이 내 의도였습니다. : "이음새가 거의없는 형상의 경우 인덱싱 된 배열이 큰 이점입니다." 사과 매우 명확하지 않았습니다. 이것을 염두에두면 결론 2에 여전히 동의하지 않겠습니까? 많은 감사. –

+0

IMHO, 스트립/팬 프리미티브 (솔기가없는 ot 포함)는 인용구에 명시된 바와 같이 색인 된 지오메트리의 잘못된 사용을 의미하지 않습니다. – Luca

관련 문제