2012-03-03 7 views
1

많은 메쉬를 한 번에 렌더링하는 방법을 찾고 있으므로 각 메쉬에 그리기 호출을 할 필요가 없습니다. 저는 여기서 2D 렌더링을 다루고 있습니다. 사각형과 같은 전형적인 객체는 두 개의 삼각형을 가질 수 있습니다. 그러나 객체는 상당히 복잡하고 수천 개의 삼각형을 가질 수도 있습니다.OpenGL - 한 번에 개별 변형을 사용하여 여러 메쉬 렌더링

이제 각 개체는 그 자체로 이동할 수 있습니다. 개념적으로 각 "객체"에 대해 VBO (또는 VBO/IBO 쌍)를 사용하는 것이 합리적입니다. 객체가 변경되지 않는 한 각 프레임에 GPU에 업로드해야하는 모든 것은 변환 정보입니다. 위치 벡터 및 방향 값. 또는 이와 동등한 변형 행렬.

그러나이 접근법의 문제점은 초기화 할 1000 개의 VBO 및 1000 개의 IBO가있는 1000 개의 정사각형 개체의 장면과 2000 개의 삼각형을 렌더링하기 위해 각 프레임의 1000 세트의 유니폼을 1000 개의 그리기 호출로 설정하는 것입니다.

오케이. 이러한 모든 객체가 동일하면 하나의 VBO/IBO를 사용하여 유니폼 버퍼 객체를 설정하거나 유니폼 버퍼 객체를 설정하십시오 (또는 유니폼 배열이 더 적절합니다 -이 객체를 사용하는 방법을 알아야합니다). 그 각각에 대해 하나의 인스턴스 그리기 호출을 실행하여 버텍스 쉐이더가 인스턴스 번호를 사용하여 변환 데이터를 UBO에서 가져 오게합니다. 큰.

한 단계 더 나아가고 싶습니다. 난 동일하지 않은 메쉬에 인스턴스화하는 양을하고 싶습니다 : 저는 1000 개의 서로 다른 오브젝트를 가지고 있습니다. 1000 개의 별도의 버텍스/인덱스 버퍼 쌍 또는 하나의 거대한 버텍스/인덱스 버퍼 쌍으로 설명하게되어 기쁩니다. 한 번의 호출로 GPU로 tranformation 데이터를 보내고 싶습니다. 드라이버/GPU가 올바른 버텍스를 바인딩하거나 선택하게하는 것은 간단합니다.

이 작업을 수행 할 수 있습니까? SM4 형상 쉐이더를 사용하지 않고도이 작업을 수행 할 수 있습니까?

업데이트 : 나는 이것을 달성 할 수있는 잠재적 인 방법을 생각했습니다. 나는 꼭지점 속성을 변환을 포함하는 UBO에 색인을 붙일 "인스 턴싱"값으로 사용합니다. 이것을하는 방법입니까?

+1

이것은 조기 최적화의 냄새가납니다. 무엇이 당신이 이것을 * 필요로한다고 생각하게합니까?이 "1000 개체"를 정상적인 방법으로 렌더링 할 수는 없습니까? –

+0

아마도 그럴 필요는 없습니다. 그러나 나는 나의 목적을 위해 최선의 방법으로이 기술을 사용하는 법을 배우는 것에 관심이있다. 매우 많은 수의 객체를 가질 수 있기를 원합니다. 한 번의 호출로 모든 객체를 그릴 수 있다면 함수 호출 오버 헤드를 피하는 것 이상의 이점을 얻습니다. 또한 뷰포트 컬링을 얻습니다. , 무료로. –

+0

어떻게하면 뷰포트 도태가 가능합니까? 인스 턴싱은 아무 것도하지 않습니다. 그것은 할 수 없다. 실제로 인스 턴싱의 요점은 CPU 오버 헤드를 줄이는 것이므로 가능한 한 인스턴스 당 처리량을 최소화하려고합니다. 빠른 절두체 컬링 (culling)조차도 피해야합니다. –

답변

0

개체 당 하나의 VBO가 필요하지 않습니다. 모든 객체를 하나의 단일 VBO 또는 단지 작은 VBO 세트로 연결하십시오. VBO에서 gl*Pointer 함수의 데이터 매개 변수에 오프셋을 추가하거나 glDrawElementsBaseVertex을 사용하여 그리기 시간에 오프셋을 추가 할 수 있습니다. 인덱스 배열에있는 단지 4 개의 indecies 대신 모든 작은 오브젝트의 인덱스 배열을 연결하십시오. 스트립 또는 팬 프리미티브를 사용하는 경우 glPrimitiveRestartIndex이라는 특수 인덱스를 설정하면 새로운 프리미티브가 시작됩니다.

그런 식으로 사용 된 재질 설정과 전체 변형 및 셰이더 매개 변수 (텍스처, 셰이더, 셰이더 유니폼)에 의해서만 렌더링 호출을 분할해야합니다.

+0

개체가 많은 경우'glDrawArrays' /'glDrawElements' 호출을 여러 번 처리하게 될 것입니다. 필자의 경험으로 볼 때, 프레임 당 수백 개 이상을 사용하는 것은 균일 변수 나 텍스처 및 쉐이더 프로그램을 변경하지 않고도 매우 느리게 진행됩니다. 난 당신이 완전히 다른 메쉬를 가지고 많은 요소를 한 번에 그릴 수있는 OpenGL 기능에 뭔가가 있는지 궁금하네요. – axel22

+0

@ axel22 : 모든 것이 올바르게 끝나면 렌더링 할 때의 실제 병목 현상은 1st * Fillrate *, 즉 프레임 버퍼를 향한 드로잉 작업과 메모리에서의 텍스처 페치로 소비되는 총 메모리 대역폭입니다. 그리고 두 번째는 * Triangle Count *입니다. * glDraw ... * 호출은 특정 오버 헤드가 있으므로 단일 * glDraw ... *로 호출되는 렌더링 일괄 처리가 더 커집니다. 특정 프로그램을 프로파일 링해야하지만 일괄 처리 크기에 적합한 숫자는 약 0.5k ~ 2.5k 삼각형입니다. – datenwolf

+0

필자의 경우 메쉬 당 삼각형의 수는 대략 1200이며, 장면에 따라 약 1500-2500 개의 메쉬를 렌더링합니다. 나는 모든 메시를 하나의 거대한 VBO에 한번 복사하고 모든 프레임에서'glDrawArrays'를 호출하면 애니메이션이 60보다 높은 FPS로 매끄 럽다는 것을 발견했습니다. 'glDraw *'를 호출하여 각 메쉬를 개별적으로 렌더링하면 프레임 속도가 cca 5-15 FPS (GTX 650 Ti에서). 가능한 한 최소한'glDraw * '를 호출해야한다는 결론을 내 렸습니다. 내 문제는 장면이 바뀔 때마다 모든 것을 하나의 큰 VBO로 복사해야하는데, 100ms 이상 걸리므로 결함이 발생합니다. – axel22