Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use DXT1 when compressing PNGs with RGB format #76516

Merged
merged 1 commit into from
Apr 27, 2023

Conversation

clayjohn
Copy link
Member

Fixes: #58012

This now roughly matches the behaviour of Godot 3. We switched to DXT5 for RGB textures in #47370 and it's not clear why the change was made. My guess is it was just a typo.

This PR only changes the RGB format. R format is left as DXT5. Originally it used FORMAT_RGTC_R. Since I'm not sure why and I'm not sure what the tradeoffs involved are, I'd prefer to leave this PR as just fixing up the obviously broken case of RGB texture imports.

There is a quality difference between DXT5 and DXT1. Notably the DXT5 option appears slightly smoother, but comes nowhere close to the quality of BPTC with the same file size

Before
Screenshot from 2023-04-27 11-01-12

After
Screenshot from 2023-04-27 11-01-17

BPTC for reference
Screenshot from 2023-04-27 11-04-35

Original for reference
Screenshot from 2023-04-27 11-05-18

This results in much smaller file sizes with the same quality
Copy link
Member

@fire fire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember something about etcpak supporting limited formats, but I think this is fine. I don't remember the details anymore.

We had tricky bits with etc1, but those use cases have astc now.

Are we trying to optimize disk size or gpu memory size? Reducing GPU memory size is better I think.

@clayjohn
Copy link
Member Author

Are we trying to optimize disk size or gpu memory size? Reducing GPU memory size is better I think.

VRAM compression optimizes both for disk size and GPU memory size. The gains are the same for both

@Calinou
Copy link
Member

Calinou commented Apr 27, 2023

This PR only changes the RGB format. R format is left as DXT5. Originally it used FORMAT_RGTC_R. Since I'm not sure why and I'm not sure what the tradeoffs involved are, I'd prefer to leave this PR as just fixing up the obviously broken case of RGB texture imports.

Ideally, the BC4 format should be used: https://learn.microsoft.com/en-us/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-block-compression#bc4

If we can't use BC4, then BC1 (DXT1) should be used instead. We don't need green/blue/alpha channels at all, and the red channel's precision remains the same (but with 1:6 compression ratio instead of 1:4).

@clayjohn
Copy link
Member Author

This PR only changes the RGB format. R format is left as DXT5. Originally it used FORMAT_RGTC_R. Since I'm not sure why and I'm not sure what the tradeoffs involved are, I'd prefer to leave this PR as just fixing up the obviously broken case of RGB texture imports.

Ideally, the BC4 format should be used: https://learn.microsoft.com/en-us/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-block-compression#bc4

If we can't use BC4, then BC1 (DXT1) should be used instead. We don't need green/blue/alpha channels at all, and the red channel's precision remains the same (but with 1:6 compression ratio instead of 1:4).

Looks like FORMAT_RGTC_R does use BC4. The problem appears to be that ETCPAC doesn't have a pathway to compress to FORMAT_RGTC_R. So I guess we are stuck with DXT5 unless someone wants to add support for RGTC_R (its supported in the renderers already). The problem with falling back to DXT1 is that it will impact the green and blue channels. A luminance texture returns the same grayscale value for r, g, and b, while a RED texture returns a grayscale value in the r channel, but 0 in the green and blue channel

@jcostello
Copy link
Contributor

Does it have a lose on quality in the after result?

@clayjohn
Copy link
Member Author

Does it have a lose on quality in the after result?

Yes DXT1 is lower quality than DXT5, see the comparison in the top post in this PR

@fire
Copy link
Member

fire commented Apr 27, 2023

The analysis suggest we don't merge this.

@clayjohn
Copy link
Member Author

The analysis suggest we don't merge this.

What analysis is that?

@Calinou
Copy link
Member

Calinou commented Apr 27, 2023

The quality difference is hardly noticeable – it's unlikely to be something you'll pick on during gameplay, especially with higher-resolution textures. If quality is really a problem, use BPTC or lossless compression for specific textures that look bad with VRAM compression instead.

Remember that pixel art textures should not use VRAM compression in general, since they're already low-resolution.

I think this PR is a good step up from the status quo, especially as VRAM usage questions are becoming common if you've followed the AAA gaming space lately 🙂

@akien-mga akien-mga merged commit 578ca94 into godotengine:master Apr 27, 2023
@akien-mga
Copy link
Member

Thanks!

@lawnjelly
Copy link
Member

Googling does suggest that the quality for RGB should be similar for DXT1 and DXT5 (perhaps identical, as articles suggest conversion is lossless), and they both use 4 bits per pixel for color (with DXT5 having extra 4 bits for alpha):
http://blog.wolfire.com/2009/01/dxtc-texture-compression/

I did a diff on clay's posted two versions and increased the levels and there does appear to be a slight difference (assuming that these PNGs are lossless):

diff

Maybe this is down to the compressor rather than the format?

@akien-mga
Copy link
Member

Cherry-picked for 4.0.3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

VRAM texture compression always uses DXT5 codec
6 participants