godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.34k stars 21.06k forks source link

ETC2 compression support #8457

Closed ghost closed 7 years ago

ghost commented 7 years ago

I'm opening a new issue since there doesn't appear to be an open issue for this.

We can adapt the Apache-licensed etc2comp for this feature (a blog post about it here).

Calinou commented 7 years ago

I think this is already supported in Godot 3.0 - Godot will create both S3TC and ETC2-compressed variations of a texture by default, if it's set to use GPU compression.

ghost commented 7 years ago

@Calinou I don't think so. All I'm seeing is etc1 and s3tc (see also the modules directory), but not etc2.

ghost commented 7 years ago

A little bit of background on this: the quality of the VRAM compressed textures using the built-in encoder can produce significantly bad artifacts (I can post some images if anyone's interested, but simply put, we're getting unusable output), while etc2comp produces much better looking textures.

ghost commented 7 years ago

Some screenshots (uncompressed vs VRAM for the 512x512 albedo texture, prepared in substance painter),

yuxocz cyv2qx

Update: These screenshots are from the editor on desktop, on which apparently only S3TC is supported (as of now). Given that Godot targets GL3.3 on desktop which doesn't mandate ETC2, we also need to fix S3TC encoder eventually for desktop.

akien-mga commented 7 years ago

cc @reduz: apparently this is on the roadmap, do you have something specific in mind for this or can @tagcup get started?

reduz commented 7 years ago

No, feel free to add etc2 support andd fix etc1 if possible for 3.0

On Apr 24, 2017 8:41 PM, "Rémi Verschelde" notifications@github.com wrote:

cc @reduz https://github.com/reduz: apparently this is on the roadmap, do you have something specific in mind for this or can @tagcup https://github.com/tagcup get started?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/8457#issuecomment-296785463, or mute the thread https://github.com/notifications/unsubscribe-auth/AF-Z26yacBXjnNA9gIeQEJ9ASWS6J_eSks5rzOzkgaJpZM4NB66U .

ghost commented 7 years ago

Great! etc2comp can do ETC1 too, so I think I'll first add modules/etc2comp and wire ETC1 encoding/decoding to etc2comp as the initial step. I guess we can eventually remove modules/etc1.

ghost commented 7 years ago

@reduz, I'd like to make use of the quality slider for VRAM too, is that OK with you? Actually, current ETC1 compressor also has a quality level setting, but the setting is hard-coded here to be low quality at the moment.

Hopefully, the naming ("lossy", "VRAM") in the importer window won't be confusing though, given that ETC is also lossy.

reduz commented 7 years ago

Sure, feel free! I never found any compressor for vram that needed it so if it does, go ahead! Keep in mind that for vram, all quality changes is compression time, not disk size like lossy. And since importing is only done once and then cached, there is little reason to use anything other than high quality.

On Apr 24, 2017 11:31 PM, "Ferenc Arn" notifications@github.com wrote:

@reduz https://github.com/reduz, I'd like to make use of the quality slider for VRAM too, is that OK with you? Actually, current ETC1 compressor also has a quality level setting, but the setting is hard-coded here https://github.com/godotengine/godot/blob/master/modules/etc1/image_etc.cpp#L120 to be low quality at the moment.

Hopefully, the naming ("lossy", "VRAM") in the importer window won't be confusing though, given that ETC is also lossy.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/8457#issuecomment-296828183, or mute the thread https://github.com/notifications/unsubscribe-auth/AF-Z27wcXwASWzVpsZsHt_TOO0EZEIRIks5rzRStgaJpZM4NB66U .

ghost commented 7 years ago

Cool, I'll do that! So I found these numbers for etc2comp, according to which after 65%, quality gains per second (in terms of PSNR) start to shrink. So maybe 70 or 80 is a good default.

BTW, etc2comp can also run in parallel (# of threads is one of the parameters of the encoder). Is it OK if I add an option for that in the editor?

reduz commented 7 years ago

For number of threads, just use the OS function that detects the number of cores, I guess that should be enough.

On Apr 25, 2017 12:12 AM, "Ferenc Arn" notifications@github.com wrote:

Cool, I'll do that! So I found these numbers http://richg42.blogspot.ch/2016/10/etc2comps-effort-parameters-impact-on.html for etc2comp, according to which after 65%, quality gains per second (in terms of PSNR) start to shrink. So maybe 70 or 80 is a good default.

BTW, etc2comp can also run in parallel (# of threads is one of the parameters of the encoder). Is it OK if I add an option for that in the editor?

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/8457#issuecomment-296836624, or mute the thread https://github.com/notifications/unsubscribe-auth/AF-Z24YLNrVffB1QbZ2BAcQqcfiZGzsdks5rzR4wgaJpZM4NB66U .

ghost commented 7 years ago

I have a few quick questions about mipmaps. Based on what I'm seeing in etc1 module here, am I right that encoded image (in the original size) is also counted among mipmaps (meaning, the return value of get_mipmap_count())?

Something feels wrong here, because for lossy, we add +1 to get_mipmap_count() here.

ghost commented 7 years ago

Oh, wait. Both loops loop over get_mipmap_count()+1 items actually, so I gess get_mipmap_count() does not include the original image.

reduz commented 7 years ago

Ah yes, it's only for mipmaps.

On Apr 25, 2017 6:04 PM, "Ferenc Arn" notifications@github.com wrote:

Oh, wait. Both loops loop over get_mipmap_count()+1 items actually, so I gess get_mipmap_count() does not include the original image.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/8457#issuecomment-297079469, or mute the thread https://github.com/notifications/unsubscribe-auth/AF-Z28-E4qH8rCVU6EO7KOQEwGSjwQskks5rzhl2gaJpZM4NB66U .

ghost commented 7 years ago

Currently, ETC1 module manually converts the image to RGB8. For specular texture, this means roughness will be dropped.

So the correct path forward seems to be to check the format, and use the proper ETC2 format. Just wondering, would that simply work if I feed an ETC2 texture? Or do you need to make additional changes in the renderer code as well?

ghost commented 7 years ago

I also just realized that etc2comp does encoding only, I'll need to get the decoding code elsewhere :(

ghost commented 7 years ago

I'm trying to test whether things are working or not right now, and I bumped into another issue. When we import using VRAM, it seems both s3tc and etc files are created. Which one of those is actually used when drawing in the editor screen? And can we change it?

reduz commented 7 years ago

On PC, only s3tc is created, while on mobile, etc1 and etc2 supported corresponding to gles2 and gles3 hw support.

Godot by default imports s3tc, etc1 and should import etc2.. which are the most common, although it supports more formats (ie, pvrtc). This needs to be eventually made configurable per project.

On Apr 25, 2017 10:12 PM, "Ferenc Arn" notifications@github.com wrote:

I'm trying to test whether things are working or not right now, and I bumped into another issue. When we import using VRAM, it seems both s3tc and etc files are created. Which one of those is actually used when drawing in the editor screen? And can we change it?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/8457#issuecomment-297150872, or mute the thread https://github.com/notifications/unsubscribe-auth/AF-Z26n5IpiP2zvXvswbY63jG_T5e4-3ks5rzlPFgaJpZM4NB66U .

reduz commented 7 years ago

I mean, pc only supports s3tc, except for very very recent hw

On Apr 25, 2017 11:04 PM, "Juan Linietsky" reduzio@gmail.com wrote:

On PC, only s3tc is created, while on mobile, etc1 and etc2 supported corresponding to gles2 and gles3 hw support.

Godot by default imports s3tc, etc1 and should import etc2.. which are the most common, although it supports more formats (ie, pvrtc). This needs to be eventually made configurable per project.

On Apr 25, 2017 10:12 PM, "Ferenc Arn" notifications@github.com wrote:

I'm trying to test whether things are working or not right now, and I bumped into another issue. When we import using VRAM, it seems both s3tc and etc files are created. Which one of those is actually used when drawing in the editor screen? And can we change it?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/8457#issuecomment-297150872, or mute the thread https://github.com/notifications/unsubscribe-auth/AF-Z26n5IpiP2zvXvswbY63jG_T5e4-3ks5rzlPFgaJpZM4NB66U .

ghost commented 7 years ago

Maybe I'm misunderstanding what you mean by support, so let me try to be clear.

ETC2 is a mandatory part of GLES 3.0 and OpenGL 4.3, and support for it has been merged into Mesa in 2012 for Intel GPUs.

It should work on Haswell and newer Intel chipsets, as well as with ancient NVidia (OpenGL 4.3+) hardware too (example: Nvidia card GT 425M on my 7 year old laptop supports OpenGL 4.5, ).

And given that Godot 3.0 requires OpenGL ES 3.0, I don't understand why can't assume ETC2 is supported universally.

About import; the editor creates etc1 file on desktop too. But I don't know what's being used.

Back to what I'm trying to do: I managed to wire etc2comp into modules/etc1, but I can't test it, because 1) the editor won't use etc1 2) standard texture viewing/creation tools can't read the Godot specific .etc.stex files.

So are you saying that at the moment, there is no way for me to see an etc1 or etc2 in the editor?

reduz commented 7 years ago

Godot on PC actually targets OpenGL 3.3, so you should not expect ETC2 to be universal. Also, even though a lot of drivers might claim support for it (for compliance), hardware does not necessarily support it, so it will just decompress the texture upon load.

This is why, it's probably not a good idea to rely on it for PC.

On Apr 25, 2017 11:22 PM, "Ferenc Arn" notifications@github.com wrote:

Maybe I'm misunderstanding what you mean by support, so let me try to be clear.

ETC2 is a mandatory https://en.wikipedia.org/wiki/Ericsson_Texture_Compression part of GLES 3.0 and OpenGL 4.3, and support for it has been merged into Mesa in 2012 http://www.phoronix.com/scan.php?page=news_item&px=MTI0NTc for Intel GPUs.

It should work on Haswell and newer Intel chipsets, as well as with ancient NVidia (OpenGL 4.3+) hardware too (example: Nvidia card GT 425M on my 7 year old laptop supports OpenGL 4.5, ).

And given that Godot 3.0 requires OpenGL ES 3.0, I don't understand why can't assume ETC2 is supported universally.

About import; the editor creates etc1 file on desktop too. But I don't know what's being used.

Back to what I'm trying to do: I managed to wire etc2comp into modules/etc1, but I can't test it, because 1) the editor won't use etc1 2) standard texture viewing/creation tools can't read the Godot specific .etc.stex files.

So are you saying that at the moment, there is no way for me to see an etc1 or etc2 in the editor?

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/8457#issuecomment-297168997, or mute the thread https://github.com/notifications/unsubscribe-auth/AF-Z2ycxmkhmfiiojaR59k7bCzCC9IeIks5rzmQdgaJpZM4NB66U .

ghost commented 7 years ago

That Godot 3.0 is targeting OpenGL 3.3 is news to me. OK.

So, but my desktop hardware does support both ETC1 and ETC2. Is it true that, regardless of the presence of the support there is still no way for me to get an ETC1 texture on the editor? Or do you have any idea how I can test the new ETC1 encoder on desktop?

reduz commented 7 years ago

I suppose opengl code should check for etc1 availability to enable it

On Apr 25, 2017 11:45 PM, "Ferenc Arn" notifications@github.com wrote:

That Godot 3.0 is targeting OpenGL 3.3 is news to me. OK.

So, but my desktop hardware does support both ETC1 and ETC2. Is it true that, regardless of the presence of the support there is still no way for me to get an ETC1 texture on the editor? Or do you have any idea how I can test the new ETC1 encoder on desktop?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/8457#issuecomment-297174613, or mute the thread https://github.com/notifications/unsubscribe-auth/AF-Z22hJMwsNxG15Kg_H6Oxi8YvQLcV-ks5rzmmJgaJpZM4NB66U .

ghost commented 7 years ago

I take that as a no :)

Well, OK. I guess I'll try to do this: I'll modify _compress_etc such that at the end, it will also write a .pkm file each time it is called. I can then open this will Mali Compression Tool for example.

BTW, I'm a bit confused about the choice of format. You mentioned that on desktop, Godot uses S3TC, but that's a patent-encumbered format, and Mesa supports it only through 3rd party libraries on systems with libxtc_dxtn installed. I'm not a lawyer, but using S3TC sounds like a going into legal minefield to me.

ghost commented 7 years ago

According to to Wikipedia, S3TC patents expire on October 2, 2017 (maybe slightly after Godot 3.0 launch date).

ghost commented 7 years ago

OK, so I manually saved the data in _compress_etc as .pkm, and they look fine in Mali Compression Tool. It seems to be working fine.

I'll next try to introduce quality option controllable from the UI, and turn on support for ETC2 compression, and submit a PR at that point.

I'll still need to add etc2 decompression, since etc2comp doesn't come with any decoders.