Jump to content
  • Advertisement
Sign in to follow this  
mancubit

Enhancing precision of 8bit RGB channels by utilizing the 8bit Alpha channel

This topic is 2677 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Although the topic name says it all: i am searching for a good way to improve precision of RGB channels (Rendertarget is a DXGI_FORMAT_R8G8B8A8_UNORM) by utilizing the 8bits of the remaining alpha channel. I guess thats what the DXGI_FORMAT_R10G10B10A2_UNORM does. But what if i am stuck to the 8bit per channel, how can i achieve higher precision? The only method i can think of, is to "assign" each rgb-component 2 bits of the alpha channel by doing some bit shift tricks, but i dont know how to do it exactly..

any suggestions?

Share this post


Link to post
Share on other sites
Advertisement
It would work if you used the Load Function. You could not use any filtering because that would destroy the information due to blending. So, if you are ok with no filtering, then you can use some bit shifting to get the extra precision, but you would be better off using the 1010102 format.

Share this post


Link to post
Share on other sites
i read deeper into bit operators and finally got something that seems to work. For anyone who needs something like that, here are my encode/decode functions


float4 encode10(float3 value)
{
// encode components of value to 10 bits by utilizing the alpha channel
int ir = value.r * 1024;
int ig = value.g * 1024;
int ib = value.b * 1024;

int a = 0;

a = (ir & 3);
a = (a << 2 ) | (ig & 3);
a = (a << 2 ) | (ib & 3);

int hr = (ir & 1020) >> 2;
int hg = (ig & 1020) >> 2;
int hb = (ib & 1020) >> 2;

float4 result;
result.r = (float)hr / 256.0f;
result.g = (float)hg / 256.0f;
result.b = (float)hb / 256.0f;
result.a = (float)a / 256.0f;

return result;
}

float3 decode10(float4 encoded)
{
int hr = encoded.r * 256.0f;
int hg = encoded.g * 256.0f;
int hb = encoded.b * 256.0f;
int a = encoded.a * 256.0f;

int or = (hr << 2) | (a >> 4);
int og = (hg << 2) | ((a >> 2) & 3);
int ob = (hb << 2) | (a & 3);

float3 result;
result.r = (float)or / 1024.0f;
result.g = (float)og / 1024.0f;
result.b = (float)ob / 1024.0f;

return result;
}


edit: ok i guess now i have some troubles with linear filtering? hmm..that makes this solution kind of unusable for me...
is there anything i can do? i don't think, it's possible to overcome this problem, is it?

@smasherprog:
thanks for your answer, but what do you mean with "the load function"?

Share this post


Link to post
Share on other sites
Packing higher-precision colour data into an RGBA texture was very common on platforms like the Xbox(original), PS2, Wii, which didn't support "high precision" textures... Usually an alternate colour space would be used, such as LogLUV, RGBM, etc

Share this post


Link to post
Share on other sites
You have to do your own filtering on the texture using multiple load()'s in the pixel shader. Instead of using Sample() to retrieve a pixel from the texture. But, bit-wise operators weren't available till 4.0, so you should use the 1010102 texture for the increased resolution because hardware texture filtering is better than the manual filtering you will have to do.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!