-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
DXT5/BC3 S3TCSRGB compressed texture is rendering in linear colour space (?) #6763
Comments
Thanks for putting compressed textures through their paces! It's good to make sure it's all working properly. The ProblemI've completed a survey of WebGL's colour handling, and how various people have tried to solve it. The problem is that WebGL just treats compressed textures as the darker color space. I believe that OpenGL has some facilities for adjusting this, but they do not exist in WebGL. The good news is, everything in that color space is handled properly. I took your PNG and converted it to linear and SRGB PVR formats, then sampled individual pixels with PVRTexTool. The linear pixels have lower values than the SRGB pixels. However, both textures render exactly the same in WebGL (and they render darker than desired). Thus, we prove that WebGL is getting the same color values from the different textures, because it knows what color space they're encoded in. It's just getting that color space consistently dark. Possible SolutionsIt's possible to write shader code to apply gamma correction to texture samples, as part of a fully color managed pipeline. This is impractical for Phaser right now. The more practical solution is to brighten the image instead. This is what many projects appear to have done around the web - but it's always been haphazardly implemented. Everybody gets this wrong! Projects borrow test images from other projects, and update them to newer formats like ASTC, but fail to apply the color adjustments, so some of their images render correctly and some render dark, within the same demos. This appears to be a very sparsely understood area of WebGL texture handling. A Practical SolutionHere's what I've found to be the best solution:
Lightening ImagesI used ImageMagick to correct PNG brightness. This is the OG of image adjustment tools and it does the job right, so far as I can tell. I have assumed that the issue is indeed sRGB/linear color conversion, and not some hidden gamma value. I follow their discussion of sRGB Colorspace Correction. Basically, sRGB is a bit more complicated than a simple gamma curve, so it's best to be very specific about color conversion. That boils down to the following command: magick image.png -set colorspace RGB -colorspace sRGB image-lightened.png You can probably find other tools to do colorspace correction, but this one is direct and easy to automate. Converting to Compressed TexturesNow encode your compressed textures from the new lightened data. Converting with TexturePackerTexturePacker will do this happily. Import the lightened image to a new project, select the appropriate encoding, and ensure that you've disabled all extrusion, margins etc. You just want the same image, with new encoding. TP also supports command-line encoding, if you have several types of encoding to do. Accessibility: buy TexturePacker to access compressed texture options. Converting with PVRTexToolPVRTexTool is also very useful. It's not a texture packer, just a texture encoder, but the GUI is extremely good at showing you exactly what's going on with compressed textures. It also supports generating MIPMaps if you know exactly what you're doing (this is a quick way to crash WebGL, because MIPMaps have very strict requirements - basically, don't use MIPMaps unless your texture width and height are powers of two). It can also do command-line encoding, for those automated pipelines. Accessibility: PVRTexTool is free, but requires a developer account to access the download. Converting with ImageMagickI was unable to find documentation for using ImageMagick to create the compressed textures directly, but it wouldn't surprise me if somebody out there has figured it out. Accessibility: "magick" with a "K". ConclusionWebGL compressed textures must be lightened before encoding. Fortunately, the tools to do this are accessible. I hope this helps get the most out of compressed textures! |
Thanks for providing the detailed instructions on how to convert the texture image 👍 |
Hm, still running into issues with the rendering (not sure if this should be a separate ticket) where semi transparent alpha images are rendering as solid colour https://codepen.io/mikewong/pen/NWmxKVa Converted to DXT5 with Texture Packer to: Which when previewed, looks like this: But in Phaser 3.70.0 (doesn't run in Phaser 3.80.1 due to #6756), it looks like this: (note the squares underneath the arcades) I'm loading the full atlas above via the multi texture atlas route in 3.80.1 as that renders but still has solid colour where there should be semi transparent pixels |
Ah, changing it to
Edit: That said, it is working here: https://codepen.io/mikewong/pen/NWmxKVa?editors=0010. Maybe my file is the issue, it's been a while since I last looked it Edit2: Rexported the texture with Texture Packer which got it loading but even with 3.80.1 which solves the loading issue but looks like the step of lightening ruins the semi transparency areas. (What it should look like on the left, what it looks like with DXT5 sRGB on the right) |
Apologies, I didn't see this until just now. GitHub is not very good at showing me updates for some reason! This is difficult to debug without looking at the actual files, I'm afraid. Is it possible to link the relevant files? Original, lightened, and compressed would give me good points to check. Obviously the texture was encoded incorrectly - it looks like the alpha is 1-bit, which looks more like DXT1/BC1 than DXT5. Or maybe premultiplication did something unexpected. |
Version
Description
Using an example image and compressing to DXT5 SRGB with pvrtextool, it renders too dark (in linear colour space?)
Original image
PVR Tex Tool settings
Rendered image
Example Test Code
Codepen: https://codepen.io/mikewong/pen/qBwdyaa
Additional Information
The text was updated successfully, but these errors were encountered: