2009-02-26 4 views
2

필자가 작업중인 일부 입자 시스템 눈 사탕의 속도를 높여야합니다. 눈 사탕은 첨가제 혼합, 축적 및 입자에 대한 자국과 노을을 포함합니다. 지금은 부동 소수점 이미지 버퍼로 손으로 렌더링하고 마지막 순간에 unsigned char로 변환 한 다음 OpenGL 텍스처로 업로드합니다. 광선을 시뮬레이트하기 위해 나는 다른 해상도와 다른 오프셋에서 같은 텍스처를 여러 번 렌더링합니다. 이것은 너무 느리다는 것을 증명하고 있으므로 뭔가를 바꾸려고합니다. 문제는 내 dev 하드웨어가 Intel GMA950이지만 대상 컴퓨터에 Nvidia GeForce 8800이 있기 때문에이 단계에서 OpenGL을 프로파일 링하는 것은 어렵습니다.그래픽 : 부동 소수점 집적 이미지가있는 최상의 성능

나는 매우 비과학적인 프로파일 링을 수행하여 대부분의 속도 저하가 float 이미지를 처리 ​​할 때 발생한다는 것을 발견했습니다. 모든 픽셀을 페이드 아웃하기 위해 상수로 스케일링하고 float 이미지를 부호없는 chars로 변환하고 그래픽 하드웨어. 그래서, 최적화를 위해 다음과 같은 옵션을 찾고 있어요 :

  • 가 SSE2 어셈블리를 사용하여 16.16 구성
  • 최적화 플로트 작업 (이미지 버퍼가 수레의 1024 * 768 * 3 배열 고정 된 지점에서 UINT32 년대와 수레를 교체)
  • 사용 OpenGL을 축적 버퍼 대신 float 배열
  • 사용 OpenGL을의 부동 소수점 FBO의 대신 float 배열의
  • 사용 OpenGL은 픽셀/버텍스 쉐이더

을 가지고 이러한 가능성을 가진 경험이 있습니까? 어떤 생각, 조언? 내가 생각하지 못한 다른 것?

+0

스크린 샷을 볼 수있는 채널이 있습니까? – Peter

답변

4

문제는 단순히 처리해야하는 엄청난 양의 데이터입니다.

플로트 버퍼의 크기는 9 메가 바이트이며 두 번 이상 데이터를 터치합니다. 대부분의 가능성이 렌더링 루프는 다음과 같이 다소 같습니다

  • 지우기
OpenGL을에 부호없는 바이트
  • 업로드로 변환이 뭔가를 (사용 읽기 및 쓰기) 렌더링 버퍼

    많은 데이터가 이동하기 때문에 캐시가 캐시보다 훨씬 크기 때문에 캐시가 많은 도움을 줄 수는 없습니다. 모든 픽셀을 5 번 터치한다고 가정 해 봅시다. 그렇다면 느린 주 메모리에서 45MB의 데이터를주고받습니다. 45mb는 많은 양의 데이터처럼 들리지는 않지만 거의 모든 메모리 액세스가 캐시 미스로 간주됩니다. CPU는 데이터가 도착하기까지 대부분의 시간을 소비합니다.

    렌더링을 수행하기 위해 CPU를 사용하고 싶다면 할 수있는 일이별로 없습니다.몇 가지 아이디어 : 비 일시적로드 및 저장을 위해 SSE를 사용

    • 는 도움, 그들은 꽤 귀하의 작업을 복잡하지만 (당신은 당신의 읽기 및 쓰기 정렬 할) 수 .

    • 렌더링을 타일로 나누어보세요. 예 : 작은 사각형 (256 * 256 정도)에서 모든 것을하십시오. 이 배경의 아이디어는 캐시에서 실제로 이점을 얻는 것입니다. 예를 들어 사각형을 지우면 전체 비트 맵이 캐시에 저장됩니다. 상대적으로 느린 주 메모리에서 데이터를 가져올 필요가 없으므로 이제는 렌더링 및 바이트 변환이 훨씬 빨라집니다.

    • 마지막 수단 : 입자 효과의 해상도를 줄입니다. 이것은 당신에게 시각적 인 질을 희생시키면서 돈을 벌 수있는 좋은 기회가 될 것입니다.

    가장 좋은 해결책은 렌더링을 그래픽 카드로 옮기는 것입니다. 요즘 질감 기능에 대한 렌더링이 표준입니다. OpenGL을 사용하려면 확장 기능을 결정해야하기 때문에 조금 까다 롭지 만 일단 작동 시키면 성능에 문제가 없습니다.

    Btw - 정말 부동 소수점 렌더링 타겟이 필요합니까? 픽셀 당 3 바이트를 버리면 성능이 크게 향상됩니다.

  • +0

    답장을 보내 주셔서 감사합니다! 나는 원래의 질문에서 이것을 명확하게하지 않았지만 나는 플로트 이미지를 필요로하는 멋진 산책로를 떠나기를 정말로 좋아합니다. 그래서 오랫동안 부드럽게 그들을 퇴색시킬 수 있습니다 ... – damian

    +0

    당신은 반 플로트 또는 16 비트를 사용할 수 있습니다 채널 당 정수 다음에 ... –

    1

    수동 코드를 스프라이트로 바꿔보십시오. 알파가 10 % 인 OpenGL 텍스처. 그런 다음 화면에 그 중 많은 부분을 그립니다 (전체 화면을 얻으려면 같은 위치에있는 10 개).

    +0

    감사하지만 스프라이트 렌더링에서 성능 문제가 발생하지 않습니다 (어쨌든 단일 픽셀 만 그리기 때문에). – damian

    +0

    내가 말했듯이 :이 그림을 그리지 않고 각 입자를 여러 개의 반투명 스프라이트로 대체하십시오. 한 곳에서 그리는 스프라이트가 많을수록 더 많은 "빛"을 얻을 수 있습니다. –

    +0

    나는 원래의 질문에서 이것을 분명하게하지는 않았지만, 나는 좋은 산책로를 떠나기를 정말로 좋아하고, 빛은 보조적이다. 멋진 산책로는 이미지를 떠 다니는 것이 필요하므로 오랫동안 부드럽게 페이드 아웃 할 수 있습니다. – damian

    1

    "수동"이라 함은 픽셀을 찌르는 데 CPU를 사용한다는 것을 의미합니다. 대신 OpenGL을 사용하여 텍스처가있는 폴리곤을 그릴 때 할 수있는 일은 꽤 빠르다고 생각합니다.

    +0

    hanks; 나는 그래픽 하드웨어에서 픽셀을 파고 (poking)하지 않고 오히려 부동 소수점 배열에서 첨가제 블렌딩을 사용하여 텍스쳐로 그린다. 텍스처 폴리곤을 직접 사용하는 가장 큰 문제점은 FBO에 대한 액세스/수정이므로 시간이 지남에 따라 페이드 아웃 할 수 있습니다. – damian

    2

    거대한 입자 시스템의 렌더링 계산을 GPU로 옮기는 것이 가장 좋습니다. GPU는이 작업을 가능한 한 빨리 수행하도록 최적화되어 있습니다.

    아론이 맞습니다 : 각 입자를 스프라이트로 나타냅니다. SSE2를 사용하여 공간에서 스프라이트의 움직임 (예 : 프레임 당 위치를 누적)을 계산할 수 있지만 OpenGL을 통해 GPU에 모든 첨가제 블렌딩 및 누적을 수행합니다. (스프라이트 그리기는 충분히 쉽게 할 수 있습니다.) 쉐이더 ("프로"방식)에서 수행하거나 누적 버퍼로 렌더링하거나 뒤로하거나, 단순히 CPU에서 추가 스프라이트를 생성하여 흔적을 처리하고 흐리게 처리 할 수 ​​있습니다 그 흔적을 래스터 라이저에 던지십시오.