
[ad_1]
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:
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 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:
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]