Java-Gaming.org
Java4K - to go         Javadoc:
Featured games (67)
games approved by the League of Dukes
Games in Showcase (∞)
games submitted by our members



News: Read the Java Gaming Resources or peek at the official java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  Print  
  texture compression  (Read 1911 times)
0 Members and 1 Guest are viewing this topic.
Offline Nate

JGO Neuromancer
****

Posts: 1028
Medals: 26


mooooo


« on: 2010-02-06 09:44:15 »

I have a game with 100mb+ in sprites. I only need a subset at any given time, so I don't load them all in memory at the same time. What can do I to reduce the file size of my game? What would be the suggested lossy compression?

Is this relevant?
http://blog.wolfire.com/2009/01/dxtc-texture-compression/

Offline Riven
« League of Dukes »

JGO Kernel
*****

Posts: 5495
Medals: 202


Hand over your head.


« Reply #1 on: 2010-02-06 10:25:32 »

Yes. It is relevant.

Hi, appreciate more people! Σ ♥ = ¾

Learn how to award medals... and work your way up the social rankings
Offline Nate

JGO Neuromancer
****

Posts: 1028
Medals: 26


mooooo


« Reply #2 on: 2010-02-06 10:26:55 »

Ok, I will look further into DXTC. I'm guessing it is the way to go since another option was not presented?

Games published by our own members! Go get 'em!
Offline Riven
« League of Dukes »

JGO Kernel
*****

Posts: 5495
Medals: 202


Hand over your head.


« Reply #3 on: 2010-02-06 10:28:40 »

DXT{1|3|5} is uncompressed on the fly by the GPU.

Do not use DXT on gradients.

Hi, appreciate more people! Σ ♥ = ¾

Learn how to award medals... and work your way up the social rankings
Offline princec
« League of Dukes »

JGO Kernel
*****

Posts: 7789
Medals: 76


Eh? Who? What? ... Me?


« Reply #4 on: 2010-02-06 10:41:58 »

DXT is also useful where you need a lot of textures in a scene.
Otherwise you might want to look at JPEG to compress your textures if all you're worried about is download size / disk space, which I'm having great results with.

Cas Smiley

Offline JL235

JGO Ninja
***

Posts: 660
Medals: 21



« Reply #5 on: 2010-02-06 12:51:03 »

Is this what DDS uses? I tried using DDS images instead of PNGs in one of my games and I found on several PCs at my university the game would crashing as the Intel cards were unable to handle them (or maybe old drivers to blame). Something to be aware of if your expecting your game to be able to run on office and low-end PCs.

Quote from: princec
Otherwise you might want to look at JPEG to compress your textures if all you're worried about is download size / disk space, which I'm having great results with.
Not if your expecting it to store any large blocks of colour, like a masking colour. JPEG typically messes them up.

I personally always use PNGs.

Offline Riven
« League of Dukes »

JGO Kernel
*****

Posts: 5495
Medals: 202


Hand over your head.


« Reply #6 on: 2010-02-06 13:09:06 »

Is this what DDS uses?

Yes. DDS supports multiple (mipmapped) DXT images in one file

Hi, appreciate more people! Σ ♥ = ¾

Learn how to award medals... and work your way up the social rankings
Offline Nate

JGO Neuromancer
****

Posts: 1028
Medals: 26


mooooo


« Reply #7 on: 2010-02-06 22:10:12 »

While I am really only concerned with download size, unfortunately I can't use JPEG because I need alpha.

Since I'm dealing with sprites, there is a bit of whitespace (especially for the larger sprites), even after I strip all whitespace from the edges. Because of this, DXT5 is giving me < 15% compression on average. In some cases, for spritesheets with larger sprites, the PNG is smaller than the DXT5. For spritesheets with many tiny sprites, I get up to ~30%.

I was hoping for better compression. At this point, I'm not sure DXT is worth the trouble for my specific scenario.

Offline Roquen

JGO Ninja
***

Posts: 567
Medals: 17



« Reply #8 on: 2010-02-07 03:03:54 »

If DL size is the main concern, then you could JPEG the RGB and PNG the alpha and merge.
Offline princec
« League of Dukes »

JGO Kernel
*****

Posts: 7789
Medals: 76


Eh? Who? What? ... Me?


« Reply #9 on: 2010-02-07 03:46:10 »

That's what I do - except I store both data in one file and have a customised loader.

Also, when saving the JPEGS, I use quality 1.0 (maximum) - it still provides for very good compression, but without the horrible colour artifacts.

Cas Smiley

Games published by our own members! Go get 'em!
Offline zoto

Full Member
**

Posts: 234
Medals: 7



« Reply #10 on: 2010-02-07 06:52:31 »

I use PNG images and run them threw Pngcrush. PNG supports loss less compression and alpha.
Offline princec
« League of Dukes »

JGO Kernel
*****

Posts: 7789
Medals: 76


Eh? Who? What? ... Me?


« Reply #11 on: 2010-02-07 07:22:04 »

FWIW, you are better off not compressing pngs or your alpha channels in JPEG, and using a more powerful compression like LZMA on the final jar.

Cas Smiley

Offline JL235

JGO Ninja
***

Posts: 660
Medals: 21



« Reply #12 on: 2010-02-07 07:25:35 »

While I am really only concerned with download size, unfortunately I can't use JPEG because I need alpha.
You could try saving as an 8-bit PNG. It's lossly and only allow pixels to be fully transparent or opaque, but it's also much smaller.

Offline Abuse

JGO Kernel
*****

Posts: 1859
Medals: 5


falling into the abyss of reality


« Reply #13 on: 2010-02-07 07:37:59 »

You could try saving as an 8-bit PNG. It's lossly and only allow pixels to be fully transparent or opaque, but it's also much smaller.

Only lossy in so much as you are forcing color reduction; the compression is still lossless as png uses zlib deflate.

I'm suprised nobody has suggested jpeg2000. Better quality & compression than jpeg, and supports alpha. A bit of a bitch to decompress though.
Offline Nate

JGO Neuromancer
****

Posts: 1028
Medals: 26


mooooo


« Reply #14 on: 2010-02-07 07:38:37 »

I also use PNG crush, but it doesn't reduce the file size by much.

No luck using 8-bit PNGs, my sprites have shadows and a lot of varying levels of transparency.

I very much like the idea of saving a JPG and alpha separately! I implemented it very rough and quick:
[snip, see below]
I'm seeing ~45% smaller sizes versus the input PNG. Sweet! Now I just need to make my code not nasty. Smiley

Does it make sense to use PNG at all? Would it make more sense to just write the alpha for each pixel, then the JPEG data, and let the JAR compression make it small?

This seems like a very useful utility. I'd love to hear more ideas on implementing this. Code would be fantastic as well! I plan to make it available through my (BSD) Skorpios project (which also means the code should be Android friendly). It also seems like it would fit in well in Slick.

Offline Riven
« League of Dukes »

JGO Kernel
*****

Posts: 5495
Medals: 202


Hand over your head.


« Reply #15 on: 2010-02-07 07:42:43 »

Does it make sense to use PNG at all? Would it make more sense to just write the alpha for each pixel, then the JPEG data, and let the JAR compression make it small?

PNG is simply GZ with overhead and a header.
JAR is simply GZip.

No doubt you knew that, but as princec said, LZMA is way better than GZ. Building the installer using LZMA would yield the smallest download size, if all lossless image data is not compressed in any way.

Hi, appreciate more people! Σ ♥ = ¾

Learn how to award medals... and work your way up the social rankings
Offline Nate

JGO Neuromancer
****

Posts: 1028
Medals: 26


mooooo


« Reply #16 on: 2010-02-07 08:22:22 »

It seems very difficult to find any tools supporting JPEG2000. I found one, but it converted without allowing me to specify quality. It took a 192kb file to 152kb. Not really a fair comparison but the same file ran through the (crappy) code I posted above gives 102kb.

Offline Roquen

JGO Ninja
***

Posts: 567
Medals: 17



« Reply #17 on: 2010-02-07 08:34:05 »

JPEG2000 should give better results for lower bit-rates.  The trick here is that's more expensive method that JPEG and you'll be stuck with a pure Java decoder.  My gut feeling is it's probably not worth the hassle.  If I remember correctly there are patent issues with JPEG200...but don't quote me on it.
Offline Nate

JGO Neuromancer
****

Posts: 1028
Medals: 26


mooooo


« Reply #18 on: 2010-02-07 13:26:16 »

I've improved my code a bit. It writes the alpha data, then the JPEG data to the same file (which I've cleverly dubbed ".img"). If I give it a 192kB PNG, it gives me a 540kB IMG file. If I zip that file it becomes 66.6kB, with LZMA it becomes 61.6kB. 68% smaller! Sweet!

To be fair, there is a noticeable loss of quality, probably because I'm not setting the JPEG quality. Whatever the default is must be pretty low. I'll have to figure out how to pass my InputStream to setOutput later, gotta run right now! The ImageIO API is rubbish!

Here are the classes:
[snip, see below]
Any comments, criticisms, or improvements are very welcome!

Offline Nate

JGO Neuromancer
****

Posts: 1028
Medals: 26


mooooo


« Reply #19 on: 2010-02-08 01:06:07 »

Ok, the latest will now always be here:

IMGEncoder.java
IMGDecoder.java

When I write the alpha, if it is 0 (transparent) or 0xFF (opaque) it is followed by the number of times that value is repeated. This greatly decreased the size of the resulting IMG file, and also results in a smaller file once ZIP'ed or LZMA'ed.

The main method in IMGDecoder writes out a PNG so you can see what the round trip has done to your image. See here for some code that loads the IMG into an OpenGL texture.

I look forward to any feedback or optimization ideas you might have for IMGDecoder. Optimizing IMGEncoder isn't nearly as important.

Edit: My sprites are down to ~30mb from ~110mb! Cheesy That is after LZMA and with JPEG quality of 0.75.

Pages: [1]
  Print  
 
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.16 | SMF © 2011, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.379 seconds with 21 queries.