브라우저에서 하나의 거대한 스프라이트 시트 또는 많은 (10000) 다른 PNG를 사용하는 것이 가장 좋습니까?


33

jQuery에서 약 10000 개의 32x32 타일을 사용하는 게임을 만들고 있습니다. 지금까지, 나는 그것들을 모두 별도로 사용했습니다 (스프라이트 시트 없음). 평균지도는 약 2000 개의 타일 (때로는 재사용 된 PNG 및 모든 개별 div)을 사용하며 성능 범위는 안정적인 (Chrome)에서 약간 느긋한 (Firefox)까지입니다. 이 div 각각은 CSS를 사용하여 절대적으로 배치됩니다. 새로운 맵이로드 될 때마다 모든 틱을 업데이트 할 필요는 없습니다.

gameQuery처럼 CSS 배경 위치 지정을 사용하여 div에 스프라이트 시트 메서드를 사용하는 것이 더 좋습니까?

미리 감사드립니다!


3
도대체 당신이지도를 위해 10,000 타일을 필요로하는 곳? 사용자 측에 모든 맵을 업로드 / 그리지 마십시오. 보이는 부분 만 표시하십시오. 사용자가 이동할 때 다음 섹션을로드하십시오. 모든 3D 그래픽의 작동 방식.
Deele

평균지도는 2000 개의 다른 타일을 사용합니까, 아니면 총 2000 개의 타일을 사용합니까? 만들고있는지도는 얼마나 큽니까?
Nick Larsen

하나 이상의 큰 이미지를 배경으로 사용하고 경계에 대해 다각형 충돌 감지를 수행하는 것을 고려 했습니까?
SAHornickel

답변:


50

나의 제안

작은 PNG가 너무 많으면 HTTP 요청의 크기뿐만 아니라 PNG 헤더 및 더 중요한 것은 효율적으로 압축 할 수 없기 때문에 네트워크 오버 헤드가 많이 발생합니다. 반면에 매우 큰 PNG 하나는로드하는 데 시간이 걸리고 지속적인 메모리 청크의 메모리 (1 만 타일의 경우 40MB)에 영구적으로 남아 있어야하는 단점이 있습니다.

중간 크기 : 여러 가지 합리적인 크기의 PNG (예 : 32 × 32 크기의 1024 타일)를 권장 합니다 . 어쩌면 테마별로 그룹화되어있을 수 있습니다 (예 : 산림 타일이있는 PNG, 산 타일이 있거나 다른 하나는 도시 타일이 있음-게임의 테마를 모르지만 아이디어는 얻음).

캐시 효율성에 대한 참고 사항

때문에 메모리 액세스 효율, 당신이해야 결코 너무 넓 당신의 spritesheets하지 않습니다. 128 × 8192 이미지의 타일 블리 팅은 8192 × 128 이미지의 블리 팅보다 항상 빠릅니다.

8192 × 128 이미지에서 첫 번째 타일을 블리 팅한다고 가정합니다. 간단하게하기 위해 1 픽셀이 1 바이트라고 가정합니다. 픽셀의 처음 두 줄은 이런 식으로 배치됩니다 (셀은 메모리에 바이트 번호를 포함합니다).

┌────┬────┬───┬────┬──────────┬─────┐
  0   1 │...│ 31    ....    8191 1st line of pixels: bytes 0 to 8191
├────┼────┼───┼────┼──────────┼─────┤
81928193│...│8223   ....   16383 2nd line of pixels: bytes 8192 to 16383
├────┼────┼───┼────┼──────────┼─────┤
 ..  .. │...│ ..    ....    ... 

따라서 첫 번째 제목의 첫 번째 줄 을 지우 려면 브라우저 엔진이에서 바이트 031 검색 합니다 . 두 번째 줄 을 지우려면 바이트 81928223 검색 하고 32 번째 줄 253952253983 검색 할 때까지 계속합니다 .

처리 된 총 바이트 수는 32 × 32입니다. 그러나 총 메모리 범위는 253984 바이트 이상입니다. 최신 CPU에서 이는 32 또는 33 캐시 중단을 의미 합니다 . 반대로 이미지가 128 × 8192 인 경우 메모리 범위는 4000 바이트에 불과하므로 캐시가 두 번 이상 정지되지 않습니다.

오늘날의 CPU는 매우 빠르기 때문에 캐시 스톨은 매우 비싸고 계산이 중단됩니다. 따라서 8192 × 128 이미지 대신 128 × 8192 이미지를 사용하는 것은 이론상 적어도 8 배 빠릅니다. 실제로 이것은 블리 팅이 어떻게 구현되는지에 달려 있습니다. 기본 엔진 자체가 이미지를 타일로 분할하여 문제를 줄일 수 있습니다.

이것은 올바르게 설명하기 쉽지 않으며 자세히 설명하지는 않았습니다. 나는 그것이 의미가 있기를 바랍니다!


4
"또한 메모리 액세스 효율성 때문에 스프라이트 시트를 너무 넓게 만들면 안됩니다. 128 × 8192 이미지의 타일 타일은 8192 × 128 이미지의 타일보다 항상 빠릅니다." -호기심이 많으니까 좀 더 자세히 설명해 주시겠습니까? :)
그림 셔

@DevilWithin : 나는 문제를 설명하려고 노력했다. 내가 충분히 명확하다면 알려주세요!
sam hocevar

캐시 효율성은 매우 매력적입니다. 프레임 속도와 관련하여 차이가 나는 숫자가 있습니까?
Gregory Avery-Weir

문제인지, 구현 고유의 것처럼 보이지만 OpenGL과 같은 API가 텍스처에 영향을 미치는 경우이를 고려하여 고려해야합니다. :)
Grimshaw

2
@DevilWithin : 내가 작성한 것은 CPU에만 유효합니다 .GPU는 엄청나게 평행하고 캐시 설정이 매우 다르며 자체 액세스 형식을 사용하여 임의 액세스에 최적화 된 텍스처를 저장합니다. 이것이 OpenGL에서 사각형의 2 제곱 텍스처가 권장되는 이유이며 타일셋에 대해서도 그 규칙을 따릅니다.
sam hocevar

5

지연의 가장 큰 원인 중 하나는 브라우저 요청에서 서버로의 왕복 여행이기 때문에 거대한 스프라이트 시트 중 하나가 아마도 더 나은 성능을 제공 할 것입니다. 10,000 번의 HTTP 호출은 1 만 건의 파일을 반환하는 1 번의 HTTP 호출보다 훨씬 오래 걸립니다.

게임의 구조와 만들고있는 HTML에 따라 지연을 줄이기 위해 사용할 수있는 다른 것들이있을 수 있습니다.

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