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

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

## 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 on other sites
noone has any ideas?

##### Share on other sites
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 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:

##### 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 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.

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 13
• 9
• 15
• 14
• 46
• ### Forum Statistics

• Total Topics
634060
• Total Posts
3015300
×