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

Decoding DXT5_CCxY images #10

Open
GitHubIsToxic opened this issue Feb 10, 2017 · 6 comments
Open

Decoding DXT5_CCxY images #10

GitHubIsToxic opened this issue Feb 10, 2017 · 6 comments

Comments

@GitHubIsToxic
Copy link

GitHubIsToxic commented Feb 10, 2017

How are YCoCg (DXT5_CCxY) encoded textures to be decoded in a shader?
I've tried the standard decode (taken from the original NV paper), but I'm not seeing the right results. When I encode to YCoCg manually before compressing to DXT5 with NVTT library, all is as expected.
The resulting DDS images produced by this method is clearly visually different from what crunch outputs.

I know YCoCg encoding is mentioned to be experimental. So does crunch apply do some extra tricks that require more work to decode? Or is this an issue with the encoder?

@richgel999
Copy link
Collaborator

Hi ByteHazard,
I think this is the code you are looking for:

// RGB to YCbCr (same as JFIF JPEG).
// Odd default biases account for 565 endpoint packing.
inline void RGB_to_YCC(color_quad_u8 &ycc, const color_quad_u8 &rgb, int cb_bias = 123, int cr_bias = 125)
{
const int r = rgb[0], g = rgb[1], b = rgb[2];
ycc.a = static_cast((r * YR + g * YG + b * YB + 32768) >> 16);
ycc.r = clamp_component(cb_bias + ((r * CB_R + g * CB_G + b * CB_B + 32768) >> 16));
ycc.g = clamp_component(cr_bias + ((r * CR_R + g * CR_G + b * CR_B + 32768) >> 16));
ycc.b = 0;
}

    // YCbCr to RGB.
    // Odd biases account for 565 endpoint packing.
    inline void YCC_to_RGB(color_quad_u8 &rgb, const color_quad_u8 &ycc, int cb_bias = 123, int cr_bias = 125)
    {
        const int y = ycc.a;
        const int cb = ycc.r - cb_bias;
        const int cr = ycc.g - cr_bias;
        rgb.r = clamp_component(y + ((R_CR * cr + 32768) >> 16));
        rgb.g = clamp_component(y + ((G_CR * cr + G_CB * cb + 32768) >> 16));
        rgb.b = clamp_component(y + ((B_CB * cb + 32768) >> 16));
        rgb.a = 255;
    }

@richgel999
Copy link
Collaborator

Also, the low-level transcoder (in the inc directory) doesn't do anything special with CCXY textures. It's up to the caller to convert the texture data to sRGB.

@GitHubIsToxic
Copy link
Author

So crunch really encodes to YCbCr, and not YCoCg? Is this an error in the Readme, or did I overlook something?

@richgel999
Copy link
Collaborator

Yes, looking at the code I wrote years ago, it's YCbCr not YCoCg. I'll fix the docs, sorry!

@GitHubIsToxic
Copy link
Author

Thanks, that clears up my confusion.

By the way, the NV paper (http://www.nvidia.com/object/real-time-ycocg-dxt-compression.html) mentions YCbCr only once, when it says "The RGB to YCoCg transform has been shown to be capable of achieving a decorrelation that is much better than that obtained by various RGB to YCbCr transforms [...]". This seems to imply that YCoCg would be a superior choice...

I have not yet compared the two methods, but had great results with YCoCg * DXT5 on textures that look terrible with standard DXT1 (skybox textures with smooth gradients).

@richgel999
Copy link
Collaborator

Thanks - I was aware of that. I remember experimenting with YCoCg, but I don't recall why I didn't wind up using it.

illwieckz added a commit to illwieckz/crunch that referenced this issue Feb 27, 2019
build executables in cmake output dir, not in subdirectories
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants