Is PNG suitable for textures?

I’m working on a project where I need to support users uploading models + textures onto my servers, where they will be distributed to other connected users. Of course, this requires that I choose one (or a handful) of supported file formats for models and textures. I’m not too worried about models - once the data is loaded I will probably be using my own internal format for storage. Textures, on the other hand are a bit trickier. In the interest of not re-inventing the wheel, I don’t want to mess around with rolling my own compressed format, and I don’t want to store uncompressed images for obvious reasons. After comparing formats, I settled on PNG for storing/transmitting textures internally for the following reasons:

  1. They’re lossless and reasonably well compressed.
  2. They support full 32-bit color.
  3. They support transparency.
  4. They’re not stored in DDS or other compressed formats that mobile and older desktop GPUs will/may bork on.
  5. I’ve used them for textures before and never had issues.

Taken as a whole, all of these reasons make PNG textures look like a decent option. Much to my surprise, however… jME doesn’t have a PNG loader. Loading the image really isn’t a problem for me - Java’s good ol’ built in ImageIO can load a byte array from a PNG file, and there are plenty of other loading options too. However, the fact that the engine doesn’t have a PNG loader makes me wonder if I’ve missed something important. Is there a particular reason why PNG textures are undesirable for textures and thus unsupported by the engine, or is this just a case of PNGs not being needed because the previously supported formats suffice?

1 Like

I can tell you from experience that PNG files work perfectly for me, I have yet to run into any issues, besides them being upside down but that’s my own error. All you need to do is specify the image in the Texture loader and it loads without issue, like this example:

Texture worldTex = assetManager.loadTexture("Textures/world.png");

Hope this helps!

Edit: I just read the compression part, the PNGs I use aren’t compressed (or at least I don’t think they are) Give this a shot anyway and see what happens!

1 Like

Glad to hear that… I must have made a major oversight in where I searched the Javadocs and engine sources.

Edit: Just peeked inside the AWTLoader. It’s delegating to ImageIO. That’ll do it.

1 Like

I just realized that I do have my PNGs compressed, they work just fine as they are!

1 Like

Yeah, that makes much more sense. * facepalm * I guess everyone gets their chance to look dumb, right? :stuck_out_tongue_closed_eyes:

1 Like

Welcome to the Club! :wink:

1 Like

I’ve had my own fair share of dumbness! :sweat_smile:

1 Like

Haha, thanks guys! :smiley:

1 Like

PNG is a very nice format because it has lossless compression.
However, something worth of knowing: png can support 16 bit per channel, but awt on which we rely on desktop can’t load them and will “down sample” them to 8 bits. It’s usually fine for normal maps, but it can be a problem if you rely on it for height maps. So png is not really suitable for height maps.

7 Likes

Great to know… I’ll make note of that. Heightmaps (if I wind up using them, I may use pre-generated mesh terrains) are cheap compared to regular textures (1 per world “area” vs. multiple per model x many models) so I wouldn’t even mind using an uncompressed format for them.

1 Like

Which format is then the “recommended” for 16-bit height maps?

1 Like

Also, there is something to understand about compressed formats.
Most of them are compressed until you load them in memory. For example A compressed jpg will take the exact same size in memory than a BMP (uncompressed).
However DDS files support DXT compression format that can be uncompressed on the GPU meaning that you can store the compressed data in memory, which is very interesting. Also DDS files supports up to 32 bits per channels.

4 Likes

DDS. you can even have a one channel DDS file which is really appropriate. We also have a KTX loader (KTX is chronos image format) but the loader doesn’t support compressed files so it’ sless interesting

3 Likes

Yes, naturally. My interest in compression is for reducing server storage space and network bandwidth. I do have one question… DXT compressed textures would be nice for reducing GPU memory where applicable. Is there a straightforward way in jME to apply DXT compression to an already loaded texture?

1 Like

Nope and there will never be. DXT compression/decompression algorithm (not all of them but I’m pretty sure DXT5 is in this case) are patented. We can’t use them in open source software.

1 Like

Gotcha… thought that would be the case, but it’s always worth a shot to ask. :wink:

At any rate, the only place I would think that loaded texture memory usage might be an issue for me would be mobile, and I know DXT can’t be used there. Oh well… no great loss.

1 Like

It depends,

png is fine for space relevant use cases.
Eg a mobile game, you better use png (or even jpg if quality is enough)
a game that is hevy on the gpu vram (mine is) better uses dds, as it is compressed in vram, whereas png is stored uncompressed in vram.
If for example you use a 1gb height map (eg height + normal + 4 channels of different texture masks) dds will only use 1/8 of the space with very little artifacts, so 128mb on vram.
Non transparent dxt1 is 1/8, with transparent it is 1/4, (you have a option to only use 1 bit for alpha, or to use multiple)

Another difference is loading time, dds can jut be memorymapped to gpu space (or at least just copied) png requires a somewhat expensive processing. This is noticeable, if you need to load a larger model with like 3 textures while the game is running (eg gta where city comes into view) . If you can just preload everything (eg think counterstrike, no dynamic models required) than you will be fine with either, else it might be noticeable.

2 Likes

It seems the patent is going to expire this year.

btw, @nehon Thanks so much for the explanation on these texture formats. I gained important information from this topic. :slight_smile:

I can see why I was getting black artifact on my model when was using png normal map and why my Terrain on jme does not look the same with my terrain in blender.
I am going to convert my diffuse, normal and height map textures to DDS with DXT5 format.

1 Like

is your heightmap transparent? if not use DXT1

2 Likes

Nope not transparent.
Okay I will use DXT1.
Thanks so much guys.

1 Like