Home Indie Game customized 8Bits RGBA textures YCoCg encoding decoding with 16 bits Y packing not wo

customized 8Bits RGBA textures YCoCg encoding decoding with 16 bits Y packing not wo

0
customized 8Bits RGBA textures YCoCg encoding decoding with 16 bits Y packing not wo

[ad_1]

Context: I’m engaged on a approach to get ugly GI for low finish platform (goal being Mali 400 mp GPU) via texture suggestions and texture PVS. (work in progress).

Problem: In order to bypass the precision restrict of 8bits textures (4 values with 256/64 rays), once I accumulate gentle in a number of go, I attempted to encode the consequence as YCoCg with 16bits float packing of the Y parts within the RG channel (1024 values with 65536/64 rays). However the consequence do not work as supposed, in my take a look at case I’ve no colours (white gentle to date, coloured comes later), however the decoding again to RGB present crimson and inexperienced outcomes as a substitute of shades of grey. Y (luminance) appears to be decoded again simply positive when utilized in isolation (earlier than RGB), Co Cg are untouched when saved to texture.

(all textures information are R8G8B8A8)

Note: the 2 planes on the fitting scene panels are take a look at objects with shaders that validate the algorithm, the left quad present the encoding and decoding, the fitting one is the management objects with an everyday unlit shader, as the 2 are comparable, it exhibits the consequence are appropriately encoded and decoded on this case

Here is the uncooked Encoded information as RG as Y, and CoCg as BA

RG as 16bits luminance encoding cut up (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 variety of rays to combine over body (accumulation)
            chromalum.x /= numRays;
            //flip the Y (luminance) into 16bits
            float4 lum = Float32ToIntrgba(chromalum.x);
            //encode cut up luminance (in RG) and chroma (BA)
            float4 consequence = float4(lum.x,lum.y, chromalum.y,chromalum.z);

            //return 16bit encoding to accumulation texture //show materials should reconstruct RGB from chroma lum
            return consequence;

And right here is the half that decode it again

            fixed4 colour = tex2D(_MainTex, enter.uv);
            fixed4 GI = tex2D(_GI, enter.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);
            colour += GI; //ought to masks albedo with gentle, not including gentle, presently colour is black, so add is a temp hack
            return colour;

Functions particulars are right 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 enter;
    enter =
         Value.r*fromFixed/(1)
        +Value.g*fromFixed/(255)
        +Value.b*fromFixed/(255*255)
        +Value.a*fromFixed/(255*255*255);
    return enter;
}

[ad_2]

LEAVE A REPLY

Please enter your comment!
Please enter your name here