Is there anyway to predict the size of a PNG file on memory?

Discussion and feedback on Construct 2

Post » Mon Dec 15, 2014 2:35 am

I only use medium downscaling, have not had the need for high, which can cause a lot of problems with bloated memory usage.

Also, it's correct that the final image within the GPU's memory is an uncompressed format. The texture size is always a power of 2. Even a thin line of 400 x 1 pixel becomes a texture of 512 x 512 pixels.

The texture size is W x H x 4.

A 512^2 texture is therefore 1MB.
1024^2 texture is 4MB.
2048^2 texture is 16MB.

Most GPUs (ever since OpenGL 1.3 and Dx6!) these days do support compressed texture formats (S3TC etc) which saves a lot of memory use, but to use, game engines have to support it.
B
70
S
24
G
19
Posts: 1,757
Reputation: 17,616

Post » Mon Dec 15, 2014 5:16 am

Silverforce wrote:The texture size is always a power of 2. Even a thin line of 400 x 1 pixel becomes a texture of 512 x 512 pixels.

That's not quite right. Yes, on older graphics cards the texture size is padded to a power of two. But they are not forced squared. So, in your example, the 400x1 pixel line would become a 512x1 texture.

For older graphics cards, 32x64, 128x8, 16x1024 are all valid formats that won't be padded, but taken as is. (Just a few examples)

Modern graphics cards don't have any of these restrictions anymore. They deal with non-power-of-two textures natively, and graphic languages like OpenGL (which WebGL is based on) also support NPOT textures. WebGL's only limitation is that mipmapping and wrapping is not supported for NPOT textures. (See https://www.khronos.org/webgl/wiki/WebGL_and_OpenGL_Differences#Non-Power_of_Two_Texture_Support)
Image
B
24
S
8
G
10
Posts: 1,821
Reputation: 8,279

Post » Mon Dec 15, 2014 7:47 am

Silverforce wrote:Most GPUs (ever since OpenGL 1.3 and Dx6!) these days do support compressed texture formats (S3TC etc) which saves a lot of memory use, but to use, game engines have to support it.


It looks like WebGL supports compressed textures, but not on mobile (where it would be the most useful, IMO). I guess even desktop support would be good, but it looks like the desktop implementation is a bit shaky too. :?
Don't lose your work. Backup your game with Dropbox.
B
44
S
10
G
10
Posts: 1,106
Reputation: 9,202

Post » Mon Dec 15, 2014 8:18 am

Memory usage describes how to calculate the memory use for an individual image, but remember spritesheeting and power-of-two padding will make it vary on export.

i heard that one way to optimize is to always try and keep the images to 16x16, 32x32, 64x64 in those kind of intervals so they will fit better in the spritsheet on export.

That's actually the worst size for sprites, since sprite animation frames go on a power-of-two sprite sheet with an extra 1px border added around every frame. So the ideal size is two pixels less than a power-of-two size, e.g. 14x14, 30x30, 62x62 etc. In fact I'd recommend just totally ignoring the power of two sizes and using whatever size you like and letting C2 spritesheet it on export. More info in Construct 2's export-time optimisations.
Scirra Founder
B
399
S
236
G
89
Posts: 24,530
Reputation: 195,402

Post » Mon Dec 15, 2014 9:10 am

tulamide wrote:
Silverforce wrote:The texture size is always a power of 2. Even a thin line of 400 x 1 pixel becomes a texture of 512 x 512 pixels.

That's not quite right. Yes, on older graphics cards the texture size is padded to a power of two. But they are not forced squared. So, in your example, the 400x1 pixel line would become a 512x1 texture.

For older graphics cards, 32x64, 128x8, 16x1024 are all valid formats that won't be padded, but taken as is. (Just a few examples)

Modern graphics cards don't have any of these restrictions anymore. They deal with non-power-of-two textures natively, and graphic languages like OpenGL (which WebGL is based on) also support NPOT textures. WebGL's only limitation is that mipmapping and wrapping is not supported for NPOT textures. (See https://www.khronos.org/webgl/wiki/WebGL_and_OpenGL_Differences#Non-Power_of_Two_Texture_Support)


This is all true, except not in the case of Construct 2.

Construct 2 will export your sprites to fit into the smallest power of 2 spritesheet that gets loaded into memory as a texture.

There is also no usage of compressed texture so that even large black areas take up the memory budget. I understand the constraints, mobile hardware differ greatly, thus the base needs to be covered.

Until it changes, devs need to be careful not to underestimate how much memory is actually used even for simple sprites and thus with any large project intended for mobiles, this needs to be taken into account during game design. Making a PC game offers a lot more freedom due to most PCs having 2gb vram, and many systems that use integrated GPUs like Intel HD3000/4000 etc, have a lot more due to using system ram as vram.
B
70
S
24
G
19
Posts: 1,757
Reputation: 17,616

Post » Mon Dec 15, 2014 11:44 am

tulamide wrote:Modern graphics cards don't have any of these restrictions anymore. They deal with non-power-of-two textures natively, and graphic languages like OpenGL (which WebGL is based on) also support NPOT textures.

I'm not actually sure to what extent this is really true, when it comes to memory use. OpenGL specifies non-power-of-two support in terms of rendering behavior, and AFAIK it's perfectly spec-compliant for a GPU to actually allocate a power-of-two texture, paste in a non-power-of-two image, remember the size of the image, then act as if the texture was really that size (such as by calculating texture co-ordinates relative to the image size instead of the surface size). So I don't know if "NPOT support" actually always translates in to "memory efficient NPOT textures". On top of that mobile GPUs tend to be simpler/more limited so do have NPOT limitations, and I think the square power-of-two limitation does still apply on some hardware as well. Even if non-square power of two-edges is supported, it's still hard to tell that's not using an in-memory power-of-two surface without knowing what the driver is doing.

I don't know all the answers here, so Construct 2 errs on the side of caution and spritesheets on to square power-of-two surfaces to ensure no matter what the driver pretends to support, there is minimal wasted GPU memory.

WebGL 2 (based on OpenGL ES 3) also in theory gets non-power-of-two texture support, but again it's still not obvious this also means "memory efficient". It means we get mipmaps for any size image which is nice, but that's all I would count on.

Compressed textures are a tricky area for a different reason: they are usually far less efficient at compression than PNG and JPEG, which means the compressed format has to be encoded from Javascript or the browser. No browsers support this yet, and doing it in Javascript means running in to patent issues on encoding some non-free formats, is probably slow, and there's still not one format that works everywhere. Also they are often lossy, meaning it can garble nice 2D artwork (they're designed for 3D engines where distance helps hide artefacts). So it's unlikely to be supported any time soon.
Scirra Founder
B
399
S
236
G
89
Posts: 24,530
Reputation: 195,402

Post » Tue Dec 16, 2014 3:47 pm

Ashley wrote:I'm not actually sure to what extent this is really true, when it comes to memory use. OpenGL specifies non-power-of-two support in terms of rendering behavior, and AFAIK it's perfectly spec-compliant for a GPU to actually allocate a power-of-two texture, paste in a non-power-of-two image, remember the size of the image, then act as if the texture was really that size (such as by calculating texture co-ordinates relative to the image size instead of the surface size). So I don't know if "NPOT support" actually always translates in to "memory efficient NPOT textures". On top of that mobile GPUs tend to be simpler/more limited so do have NPOT limitations, and I think the square power-of-two limitation does still apply on some hardware as well. Even if non-square power of two-edges is supported, it's still hard to tell that's not using an in-memory power-of-two surface without knowing what the driver is doing.

I understand quite well that regarding C2 it is better to trust on a known working way that is true for all platforms/gpus. It's a shame that gpu vendors don't publish inner workings. I tried to find something about it to no avail.
However, the oldest graphic card I can talk of is the GTX 460. It is almost 5 years old. From tests I made I know that it supports non-squared POTs natively. No memory is wasted. Assuming that NVidea wouldn't change the driver's behaviour to the worst for newer cards, at least non-squared POTs are supported for all NVidea GPUs in the last 5 years. I then just assumed that AMD and Intel wouldn't want to fall behind.
The rendering support is a strong argument. Indeed you can't tell if supporting them does also mean storing them memory efficient.
Image
B
24
S
8
G
10
Posts: 1,821
Reputation: 8,279

Post » Tue Dec 16, 2014 4:44 pm

GPU details are available to registered developers ; which unfortunately excludes hobbyists and most sole/indie programmers.

Maybe check the DirectX SDK docs, they're usually full of general "good advice" and up-to-date "best practices" when it comes to managing graphics resources. Obviously it doesn't cover engine specifics (for example the padding here already mentioned by Ashley), but it gives some understanding of the inner working.

Though that's only true on PC... For mobile chips, good luck understanding anything at all ; between the Android and Apple, the PowerVR and whatnot, they're all different even across the same family.
Image
Game Producer & Independent Developer - http://raphaelgervaise.com
B
24
S
9
Posts: 237
Reputation: 2,232

Previous

Return to Construct 2 General

Who is online

Users browsing this forum: No registered users and 10 guests