Hello I'm trying to do a chroma lum encoding to texture for a complex shader I'm doing. I have used unity formula for YCbCr but it doesn't seem to be reversible. Am I doing something wrong? Is there other way to get chroma lum encoding and decoding? Testing the reversibility in code: Code (CSharp): fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); float3 c = col; c = RgbToYCbCr(c); c = YCbCrToRgb(c); col = float4(c,1); return col; } Left is code result, right is original texture colors: Encoding and decoding formula lift from core shader render pipeline from unity: Code (CSharp): // // RGB / Full-range YCbCr conversions (ITU-R BT.601) // float3 RgbToYCbCr(float3 c){ float Y = 0.299 * c.r + 0.587 * c.g + 0.114 * c.b; float Cb = -0.169 * c.r - 0.331 * c.g + 0.500 * c.b; float Cr = 0.500 * c.r - 0.419 * c.g - 0.081 * c.b; return float3(Y, Cb, Cr); } float3 YCbCrToRgb(float3 c){ float R = c.x + 0.000 * c.y + 1.403 * c.z; float G = c.x - 0.344 * c.y - 0.714 * c.z; float B = c.x - 1.773 * c.y + 0.000 * c.z; return float3(R, G, B); }
YCbCr isn't reversible normally, not without some loss, but that's much worse than usual. It looks like the Cb is offset by 0.5, but I don't know if that's the fault of the encode or decode. Depending on what you're doing, YCoCg might be a better choice as it is reversible (at least some versions are).