2015-01-12 3 views
0

these awesome tutorials을 사용하여 웹 GL을 배우려고 노력했습니다. 제 목표는 캔버스 기반의 jawsJS를 대체 ​​할 수있는 매우 간단한 2D 게임 프레임 워크를 만드는 것입니다.내 간단한 webgl 데모가 너무 느린 이유

필자는 기본적으로 스프라이트를 만들고 주변을 움직일 수 있기를 원한다.

이 작업을 수행하는 데모를 정리했지만 성능 문제가 발생하여 추적 할 수 없습니다. 일단 화면에 ~ 2000 정도의 스프라이트가 생기면 프레임 속도 탱크와 나는 왜 작동하지 못합니다. 이 demo of the pixi.js webgl framework과 비교하면 ~ 30000 토끼 정도에서 (내 컴퓨터에서) 프레임을 잃기 시작합니다. 조금 실망합니다.

My demo (framework source)에는 5002 개의 스프라이트가 있으며 그 중 2 개는 이동하며 프레임 속도는 화장실에 있습니다.

pixi.js 프레임 워크를 통해 다르게 수행하려고 시도했지만, 500kloc이고 훨씬 더 많은 작업을 수행 할 수 없습니다.

this answer 나는 근본적으로 내가하고있는 일이 대략 옳다는 것을 확인했다. 나의 알고리즘은 대답과 거의 같지만 그 이상이 있어야한다.

지금까지 몇 가지를 시도해 보았습니다. 하나의 '프레임 버퍼'를 사용하여 정의 된 단일 모양으로 각 스프라이트에 대해 5000 번 번역되었습니다. 이것은 프레임 속도를 약간 도와 주었지만, pixi 데모를 닫을 수는 없었습니다 (모든 스프라이트가 같은 모양이어야한다는 것을 의미했습니다). 저는 모든 행렬 수학을 움직이지 않는 것으로 잘라 냈습니다. 그래서 그것도 아닙니다. 그것은 모두 drawArrays() 기능으로 내려 오는 것 같습니다. 단지 저를 위해 속도가 느려지지만, 단지 내 데모를 위해서입니다!

또한 텍스처 기반의 모든 항목을 제거해 보았습니다. 단편 쉐이더를 대신 간단한 블록 색상으로 대체했습니다. 그것은 사실상 아무런 차이가 없으므로 나는 dodgy 텍스처 처리를 범인으로 제거했습니다.

나는 정말로 어리석은 일을 추적하는 데 도움이 될 것입니다.

편집 : 여기 키를 잘못 이해하는 것이 틀림 없습니다. (0,0)

void main() { 
    gl_FragColor = vec4(0,1,0,1); // green 
} 

다음에 그릴까지 스프라이트를 설정합니다

attribute vec2 a_position; 

void main() { 
    gl_Position = vec4(a_position, 0, 1); 
} 

과 : 나는 슈퍼 간단한 정점과 프래그먼트 쉐이더로 변경, 기본에 바로 다시 전체를 제거 (1,1).

스프라이트가 5000 개이면 단일 프레임을 그리는 데 약 5 초가 걸립니다. 여기서 무슨 일이 일어나고있는거야?

+0

업데이트 : 진행 중이지만 아직 할 일이 있습니다. 아래의 두 가지 대답이 모두 도움이되었습니다. 한 번에 많은 스프라이트에서 정점을로드하고 1 드로를 만드는 SpriteBucket 오브젝트를 작성함으로써 성능을 크게 향상 시켰습니다. 처음에는 5000 개의 스프라이트가 하나의 버퍼에로드되는 속도가 매우 느 렸지만 실제 속도는 가장 느 렸지만 스프릿을 여러 버킷에서 500 개까지 버리면 다시 ~60fps가됩니다. 이제는 모든 질감을 다시 넣을 필요가 있습니다! – MalphasWats

답변

4

WebGLInspector 또는 실험용 canvas inspector을 크롬으로 사용하여 프레임을 호출하면 렌더링 루프가 최적화되지 않았을 때 전체적으로 이 표시됩니다.

모든 지오메트리를 렌더링하는 데 하나의 동일한 정점 버퍼를 사용할 수 있고 사용해야합니다. bindBuffervertexAttribPointer 호출을 저장할 수있는 방법입니다. 하나의 동일한 텍스처를 반복적으로 리 바인드하므로 텍스처 바인딩의 99 %를 저장할 수도 있습니다. 동일한 텍스처 단위에 다른 것을 바인딩하지 않는 한 텍스처는 바운드 상태로 유지됩니다.

상태 캐시를 사용하면 이미 바인딩 된 데이터를 바인딩하지 않아도됩니다.

gpu를 statemachine으로 보시고 my answer here을보십시오.

당신의 렌더링 루프는 당신이 가서 다음과 같은 사항을 고려할 수 최적화되면 :

  • 사용 ANGLE_instanced_arrays 확장하여 렌더링 루프에서
  • 않도록 구성하는 데이터입니다.
  • 인터레이스 된 정점 버퍼를 사용하십시오.
  • 경우에 따라 이 아닌 색인 버퍼를 사용하면 성능이 향상됩니다.
  • 쉐이더에서 몇 GPU주기를 면도 할 수 있는지 확인하십시오.
  • 개체를 청크로 분해하고 CPU 측면에서 절두체 컬링을 봅니다.
+0

감사합니다. 이것은 대부분 의미가 있습니다 (나는 GL 프로그램을 한 번도 해보지 못했습니다!). 나는 (우연히도!) 단일 버퍼를 사용하고 각 객체에 대해 같은 6 개의 꼭지점을 그려 번역 한 버전을 가지고 있었지만, 그것은 내가 기대했던 것에서 약간 나아졌지만 아직 멀었다. 내 문제는 관련이 있다고 생각하고 가능한 한 많은 정점을 하나의 버퍼에로드하려고 시도합니다. 나는 하나의 객체를 번역하는 법을 배울 수 없다는 것에 우려하고있다. 나는 모든 것을 자바 스크립트 측면에서 계산하는 것을 피하고 싶다. – MalphasWats

+0

나는 이것을 정답으로 표시 할 것입니다. 나는 어디서부터 볼 것인가에 대한 몇 가지 조언이 필요했다. 내 솔루션을 조금 더 써 보겠습니다. – MalphasWats

+0

일단 렌더 루프를 최적화하면 @NoHarmInTryings 방식을 적용 할 수 있습니다. 그러나이 접근법의 성능은 여러분이 가진 동적 객체의 양에 크게 의존한다는 것을 기억하십시오. GPU에서 모든 프레임을 모든 프레임으로 변형 시키면 성능이 향상되지 않습니다. –

1

문제는 아마도이 렌더 라인이 있습니다 : glixl.context.uniformMatrix3fv(glixl.matrix, false, this.matrix);.

내 경험에 비추어 볼 때, 각 모델의 유니폼을 webGL에서 매우 느리게 전달하기 때문에 ~ 1,000 개의 고유 모델 이후 60FPS를 유지할 수 없었습니다. 불행히도이 문제를 완화하기 위해 webgl에 균일 한 버퍼가 없습니다.

나는 CPU의 모든 정점 위치를 계산하여 하나의 drawArray 호출을 사용하여 모두 내 문제를 해결했습니다. 버텍스 수가 압도적으로 많지 않은 경우이 방법이 효과적입니다. 나는 60FPS로 2k 이동 + 회전 큐브를 그릴 수 있습니다.나는 정확히 얼마나 많은 큐브를 60FPS로 그릴 수 있는지를 기억하지 못하지만 2k보다 약간 더 높습니다. 그다지 빠르지 않으면 drawArrayInstanced을 조사해야합니다. 기본적으로 모든 행렬을 arraybuffer에 저장하고 올바른 오프셋 등을 사용하여 drawArrayInstanced 호출을 사용하여 모든 모델을 그립니다.

편집 : 또한 OP에 PIXI가 정점 업데이트 렌더링을 수행하는 방법 (균일하지 않음)을 보려면 https://github.com/GoodBoyDigital/pixi.js/blob/master/src/pixi/renderers/webgl/utils/WebGLFastSpriteBatch.js을 참조하십시오.

+0

답변 해 주셔서 감사합니다. 단순히 그 라인을 주석으로 처리한다면 아무것도 그려지지 않습니다 (분명히), 프레임 속도는 몇 가지 포인트가 올라갑니다. 지금 사용하고있는 머신에서'uniformMatrix3fv()'호출로 5000frites로 8fps를 얻었습니다. 주석 처리를하면 ~ 10까지 올라갑니다. pixi 데모는이 머신에서 떨어지기 전에 ~ 8000 개의 스프라이트로갑니다. – MalphasWats

+0

알다시피, 병 목은 그때 다른 곳입니다. 렌더링 함수에서 선을 하나씩 꺼내서 어느 것이 가장 큰 영향을 미치는지 확인하는 것이 좋습니다. GPU 상태를 변경하는 호출 중 하나 일 가능성이 높습니다. 아마 BindTexture. 아직 CPU 바운드인지 확인하려면 CPU 프로파일을 수행하십시오. –

+0

균일 한 바인딩은 확실히 ** 아닙니다 ** * 문제입니다. [그 가장 빠른 것]과 같이 문제의 일부가 아닌 거의 유일한 것입니다 (http://stackoverflow.com/questions/26564104/use- single-vertex-buffer-or-many/26568792 # 26568792) 하나는 webgl이 될 수도 있고 그렇지 않을 수도 있습니다. –

관련 문제