Welcome, Guest. Please login or register.

Login with username, password and session length

Advanced search

1411456 Posts in 69368 Topics- by 58422 Members - Latest Member: daffodil_dev

April 22, 2024, 04:52:38 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)custom 8Bits RGBA textures YCoCg encoding decoding with 16 bits Y packing not wo
Pages: [1]
Author Topic: custom 8Bits RGBA textures YCoCg encoding decoding with 16 bits Y packing not wo  (Read 2316 times)
Level 10

The archivest master, leader of all documents

View Profile
« on: November 02, 2022, 04:24:31 PM »

Context: I'm working on a way to get ugly GI for low end platform (target being Mali 400 mp GPU) through texture feedback and texture PVS. (work in progress).

Problem: In order to bypass the precision limit of 8bits textures (4 values with 256/64 rays), when I accumulate light in multiple pass, I tried to encode the result as YCoCg with 16bits float packing of the Y components in the RG channel (1024 values with 65536/64 rays). However the result don't work as intended, in my test case I have no colors (white light so far, colored comes later), but the decoding back to RGB show red and green results instead of shades of gray. Y (luminance) seems to be decoded back just fine when used in isolation (before RGB), Co Cg are untouched when saved to texture.

(all textures data are R8G8B8A8)

Note: the two planes on the right scene panels are test objects with shaders that validate the algorithm, the left quad show the encoding and decoding, the right one is the control objects with a regular unlit shader, as the two are similar, it shows the result are correctly encoded and decoded in this case

Here is the raw Encoded data as RG as Y, and CoCg as BA

RG as 16bits luminance encoding split (yellow is r+g)

BA as Chroma CoCg encoding

Here is the code that encode to chromalum in fragment:
            //chromaLum encoding
            float3 chromalum = RgbToYCoCg(irradiance);
            //divide luminance by number of rays to integrate over frame (accumulation)
            chromalum.x /= numRays;
            //turn the Y (luminance) into 16bits
            float4 lum = Float32ToIntrgba(chromalum.x);
            //encode split luminance (in RG) and chroma (BA)
            float4 result = float4(lum.x,lum.y, chromalum.y,chromalum.z);

            //return 16bit encoding to accumulation texture //display material must reconstruct RGB from chroma lum
            return result;
And here is the part that decode it back
            fixed4 color = tex2D(_MainTex, input.uv);
            fixed4 GI = tex2D(_GI, input.uv); 
            //decode GI (16bit Y -> chromalum -> RGB)
            float luminance = IntrgbaToFloat32(float4(GI.xy,0,0));      //return luminance*16;
            float3 lighting = YCoCgToRgb(float3(luminance,GI.z,GI.w));       

            GI = float4(lighting,1);
            color += GI; //should mask albedo with light, not adding light, currently color is black, so add is a temp hack
            return color;
Functions details are here:
float3 RgbToYCoCg(float3 c){
    float Y  =  0.25 * c.r + 0.5  * c.g + 0.25 * c.b;
    float Cb =  0.5  * c.r - 0.0  * c.g - 0.50 * c.b;
    float Cr = -0.25 * c.r + 0.5  * c.g - 0.25 * c.b;
    return float3(Y, Cb, Cr);

float3 YCoCgToRgb(float3 c){
    float R = c.x + c.y - c.z;
    float G = c.x       + c.z;
    float B = c.x - c.y - c.z;
    return float3(R, G, B);

float4 Float32ToIntrgba(float floatValue){
    const float toFixed = 255.0/256;
    float4 output;
    output.r = frac(floatValue*toFixed*1);
    output.g = frac(floatValue*toFixed*255);
    output.b = frac(floatValue*toFixed*255*255);
    output.a = frac(floatValue*toFixed*255*255*255);
    return output;
float IntrgbaToFloat32(float4 Value){
    const float fromFixed = 256.0/255;
    float input;
    input =
    return input;

Pages: [1]
Jump to:  

Theme orange-lt created by panic