[펌]왜 이미지사이즈를 2의 승수로 만들어야 하나? by 김윤정

그래픽 카드에 따라 다른 2의 승수가 아닌 실사이즈 이미지의 지원여부에 대해 조금 알아봤는데 미약하나마 알아본대로 정리해서 올립니다. 더불어 이미지 사이즈를 2의 승수로 했을때의 잇점도 함께 얘기해 볼까 합니다.

 


밉맵이 없는 2D 텍스쳐의 경우, 예전 부두계열 그래픽 카드에서 최대크기 256*256 의 제한과 정방형(ex.32*32, 64*64, 128*128...) 이미지의 제한이 있었는데 최근의 그래픽카드(DirectX8.0 이상을 지원하는 카드 : GeForce 2MX 이상)는 실사이즈를 대부분 지원한다고 합니다. 밉맵이 있는 경우의 2의 n승이 아닌 텍스쳐를 지원하는 그래픽 카드는 지포스 6000시리즈 정도가 가능하다고 합니다.  그러나 2MX보다 상위기종이지만 FX5700의 경우는 2의 승수가 아니면 지원이 안된다고 하네요.


나름대로 최신의 그래픽 카드라도 2의 승수에 대한 제약, 정방형에 대한 제약, 최대 이미지 사이즈에 대한 제약이 더러 있어서 실제 게임개발에 있어서 이미지를 실사이즈로 사용하는 것은 상당한 무리가 있는 것으로 보입니다. 구린 카드를 갖고 있는 유저는 우리게임 하지도 말라는 식이 아니라면 말이죠.

 

그러면 최근 출시한 게임들을 즐기는 유저들이 보유한 그래픽 카드가 DX8.0 이상을 모두 지원한다고 가정할때, 실사이즈로 이미지를 잘라 쓰는 것이 과연 좋은 방법일까요? 실사이즈 이미지로 제작하게 되면 제작노력과 시간이 단축될 것이 분명합니다. 그러나 게임의 성능면에서 역시 비추입니다.

 

DirectX 9.0c SDK October 2005 버전에 있는 도움말 중에 Performance Optimizations > Texture Size 부분의 글을 잠깐 보겠습니다.

----------------------------------------------------------------------------------------

There are a number of ways to maximize the cache performance of your application's textures.
Keep the textures small.
The smaller the textures are, the better chance they have of being maintained in the main CPU's secondary cache.
Do not change the textures on a per-primitive basis.
Try to keep polygons grouped in order of the textures they use.
Use square textures whenever possible.
Textures whose dimensions are 256x256 are the fastest.
If your application uses four 128x128 textures, for example, try to ensure that they use the same palette and place them all into one 256x256 texture.
This technique also reduces the amount of texture swapping.
Of course, you should not use 256x256 textures unless your application requires that much texturing because, as mentioned, textures should be kept as small as possible.

----------------------------------------------------------------------------------------

텍스쳐의 사이즈는 최대한 작게 유지하고 될 수 있으면 정방형을 유지하고 256*256 사이즈가 가장 빠르니까 128*128 이미지 4장의 경우, 같은 팔레트를 사용해서 한 이미지로 붙여 256*256으로 만들면 텍스쳐 전송의 양이 줄어들어 빠르다는 내용입니다. 필수는 아니지만 강력히 권고하는 인상입니다.

 

머리아픈 얘기지만 2의 승수가 될 경우 또하나의 이점은 텍스쳐의 어드레스 연산시 쉬프트 연산을 써서 이미지 처리가 굉장히 빨라집니다. 2의 승수가 아니라면 이런 식의 처리는 불가능해져서 복잡한 과정을 거치게 됩니다. 이런 것들이 한둘씩 모이면 전체적인 성능의 저하를 가져오는 요인이 되는 것입니다.

 

하드웨어적 측면이나 게임의 퍼포먼스 측면에서나 2의 승수는 선택이 아닌 필수라고 생각됩니다.

 

아래는 가마수트라에 올라온 '3D 월드에서의 2D 프로그래밍: DirectX 8의 Direct3D를 이용한 2D 게임엔진 개발(저자 : George Geczy) 에 관한 내용입니다. 참고하시기 바랍니다. (출처 : http://www.gpgstudy.com/gpgiki/DX82Din3D)

 

원문 : http://www.gamasutra.com/features/20010629/geczy_pfv.htm

----------------------------------------------------------------------------------------
There is, however, one more big difference between surfaces and textures, and you actually have to pay some attention to this one: size restrictions. The width and height of a texture is restricted in most hardware to being a power of two for each dimension, and some hardware imposes maximums and other rules on these sizes. For the width and height, power-of-two sizing means that sizes like 128, 256, 512 and 1024 are acceptable numbers. So a texture of 256 pixels wide by 256 pixels high is acceptable, and most cards will allow different width/height values such as 256x128 or 64x16. This power-of-two limitation shouldn't be a major concern, because your bitmap doesn't need to fill the available space of the texture. If you have a 96x80 pixel graphic, put it in a 128x128 texture and just specify the location of your graphic when you use the texture. If you have two 60x60 images, template them together into a single graphic and load it into a 128x64 texture. There will be some wasted space, but in the future you'll start thinking about creating graphics in sizes that will work well with texture limits.

그러나 여러분이 알아 두어야 할 텍스쳐와 서피스의 큰 차이점이 있다. 그것은 텍스쳐의 크기 에 관한 것으로, 텍스쳐의 가로와 세로 폭은 대부분의 하드웨어에서 2의 승수가 되도록 제한한다. 또 어떤 하드웨어에서는 최대 크기의 제한과 다른 제약 조건 (역주 - 부두 계열에서의 정방형 제한 등)을 갖는다. 가로와 세로의 2의 승수 제한이라는 것은 가로와 세로에 128이나, 256, 512, 1024 등을 텍스쳐의 크기로 사용할 수 있다는 의미이다. 그러므로 가로 256 픽셀 x 세로 256 픽셀 크기의 텍스쳐는 사용할 수 있으며, 대부분의 카드에서는 256 x 128, 64 x 16처럼 가로 세로가 같지 않아도 텍스쳐로 사용할 수 있다. 2의 승수 제약 조건에 대해서 특별히 큰 신경을 쓸 필요는 없는데, 여러분이 사용하는 이미지bitmap가 반드시 전체 텍스쳐를 가득 메워야 하는 것은 아니기 때문이다. 만약 96 x 80 픽셀의 이미지를 갖고 있다면, 그것을 (역주 - 96과 80보다 큰 최소의 2의 승수 폭인) 128 x 128 텍스쳐에 채워 넣고, 텍스쳐 상에서의 위치에만 신경쓰면 된다. 만약 두 60 x 60 이미지를 사용해야 한다면 그것을 한 장의 이미지로 만들어 128 x 64 텍스쳐에 넣으면 된다. 텍스쳐에 낭비되는 공간이 생기겠지만, 차근차근 텍스쳐의 크기 제한에 맞추어 이미지를 작성하는 방법에 대해서 생각하게 될 것이다

The maximum-size restriction is a bigger issue. Modern hardware allows textures of 1024x1024 or larger, even as big as 4096x4096 (which takes 64MB of video memory in 32-bit color), but some older hardware -- particularly 3dfx Voodoo products -- have a maximum texture size of 256x256. If you currently load larger images, either as a background image or as a larger templated file of small sprites, then you'll have to chop these into smaller images to be compatible. Most game designs today no longer load a large background image, since maps are usually made up of a collection of individual tiles and smaller images. There are CAPS details you can get from Direct3D 8 that will report the maximum texture sizes and other restrictions (see D3DPTEXTURECAPS_POW2, D3DPTEXTURECAPS_SQUAREONLY, MaxTextureWidth / MaxTextureHeight, and MaxTextureAspectRatio in the SDK docs).

최대 크기 제약이 가장 큰 쟁점이다. 최신 하드웨어는 1024x1024 혹은 그 이상의, 심지어는 4096x4096의(32비트 컬러에서 64MB의 메모리를 차지한다) 텍스처를 지원한다. 하지만 오래된 하드웨어-특히 3fdx Voodoo 제품-는 최대 텍스처 크기가 256x256이다. 만약 배경 그림이나 스프라이트가 들어있는 커다란 파일 같은 커다란 그림을 읽어온다면, 적절한 크기의 작은 이미지로 쪼개야 한다. 현재 대부분의 게임들은 각각의 타일과 작은 그림들이 모여서 만들어지는 맵이 일반적으로 사용되면서 더이상 커다란 배경으로 디자인되지 않는다. Direct3D 8으로부터 최대 텍스처 크기나 다른 제약을 보고 받을 수 있는 CAPS(capabilities) 항목들이 있다. ( SDK 문서에서 D3DPTEXTURECAPS_POW2, D3DPTEXTURECAPS_SQUAREONLY, MaxTextureWidth / MaxTextureHeight, and MaxTextureAspectRatio를 보라 ).

 

The D3DX utility library also lets you get a bit lazy and will automatically calculate acceptable sizes for you, so if you call D3DXCreateTexture() and ask for a 100x60 texture, the function will check the hardware capabilities and create a legal size behind your back. Same with the functions that load an image into a texture from a file. And should you have a large source image that you can't or don't want to break up into smaller parts, you can load the large file into a surface with D3DXLoadSurfaceFromFile(), and then use CopyRects() to move partial correctly-sized sections of the image to the surface of smaller textures, which you then draw with.

D3DX 유틸리티 라이브러리 또한 약간의 게으음을 제공하며 이것은 자동으로 적당한 크기를 계산해준다. 만약 D3DXCreateTexture()를 호출하면서 100x60 텍스처를 요구하면 이 함수는 하드웨어 검사를 해서 적합한 텍스처를 생성한다. 마찬가지로 파일에서 텍스처를 읽어오는 함수도 있다. 커다란 원본 이미지를 작은 조각으로 나누는 걸 할 수 없거나 원치 않는다면, D3DXLoadSurfaceFromFile()을 이용해서 서피스에 커다란 파일을 읽어올 수 있고, CopyRects()를 이용해서 화면에 그려줄 작은 텍스처의 서피스에 정확한 크기로 절단해서 옮길 수 있다.

 

A final warning before we get to the code for all this is that you should be careful of the amount of video memory you are using. If you have a 1024x1024 image template of sprites that you are loading, 32 bits per pixel, and an 800x600 screen resolution, then you will need almost 6MB of video memory (room for the front buffer, back buffer, and the texture). However if you use a number of the smaller 256x256 textures, then DirectX will automatically remove (flush) textures from video memory if the space is required to load new textures. Note that if this happens multiple times each frame you will take a performance hit.

코드를 작성하기 전 마지막 주의점은 사용중인 비디오 메모리의 크기에 주의해야 한다는 점이다. 만약 스프라이트가 들어있는 1024x1024 이미지를 읽어온다면, 32비트 컬러에 800x600 해상도에서 거의 6MB를 필요로 한다. ( 전면과 후면, 텍스처를 위한 공간 ) 하지만 작은 256x256 텍스처들을 사용한다면, DirectX는 새로운 텍스처를 읽기 위한 공간이 요구될 때 저절로 비디오 메모리로부터 텍스처를 제거(flush)한다. 매 프레임마다 이런 일이 여러번 일어난다면 퍼포먼스에 영향을 주는 것을 기억하라.


덧글

  • TW베르스퍼 2006/10/05 11:55 #

    홧;;;전문용어 난무.....orz....(털썩)
  • 김윤정 2006/10/05 19:40 #

    ...그냥 2의 배수로 만들면 빠르단 겁니다 ^^
  • TW베르스퍼 2006/10/08 16:39 #

    그런거군요+ㅅ+~
  • 이준형 2007/08/17 12:08 # 삭제

    512 1장보다 256 4장이 가볍다는 이야기.
※ 로그인 사용자만 덧글을 남길 수 있습니다.


MyADD

<script> (adsbygoogle = window.adsbygoogle || []).push({}); </script>