以下是对UnityCG.cginc文件中EncodeFloatRGBA()与DecodeFloatRGBA()两个函数的理解。
//Unity原版代码
// Encoding/decoding [0..1) floats into 8 bit/channel RGBA. Note that 1.0 will not be encoded properly.
inline float4 EncodeFloatRGBA( float v )
{
float4 kEncodeMul = float4(1.0, 255.0, 65025.0, 16581375.0);
float kEncodeBit = 1.0/255.0;
float4 enc = kEncodeMul * v;
enc = frac (enc);
enc -= enc.yzww * kEncodeBit;
return enc;
}
inline float DecodeFloatRGBA( float4 enc )
{
float4 kDecodeDot = float4(1.0, 1/255.0, 1/65025.0, 1/16581375.0);
return dot( enc, kDecodeDot );
}
//-------------
//通俗版代码
inline float4 EncodeFloatRGBA( float v )
{
float4 kEncodeMul = float4(1.0, 255.0, 65025.0, 16581375.0);
float kEncodeBit = 1.0/255.0;
float4 enc = kEncodeMul * v;//enc=(0.rgba, r.gba, rg.ba, rgb.a)
enc = frac (enc);//保留小数部分后 enc=(0.rgba, 0.gba, 0.ba, 0.a)
float4 tmp = enc.yzww * kEncodeBit;//tmp=(0.0gba, 0.0ba, 0.0a, 0.0a)
enc -= tmp; //enc=(0.rgba-0.0gba, 0.gba-0.0ba, 0.ba-0.0a, 0.a-0.0a)
return enc;//(0.r, 0.g, 0.b, ≈0.a)
}
inline float DecodeFloatRGBA( float4 rgba )
{
float4 kDecodeDot = float4(1.0, 1/255.0, 1/65025.0, 1/16581375.0);
return dot( rgba, kDecodeDot );//return 0.rgba 形象表示
}
//-------------
// Encoding/decoding [0..1) floats into 8 bit/channel RG. Note that 1.0 will not be encoded properly.
inline float2 EncodeFloatRG( float v )
{
float2 kEncodeMul = float2(1.0, 255.0);
float kEncodeBit = 1.0/255.0;
float2 enc = kEncodeMul * v;
enc = frac (enc);
enc.x -= enc.y * kEncodeBit;
return enc;
}
inline float DecodeFloatRG( float2 enc )
{
float2 kDecodeDot = float2(1.0, 1/255.0);
return dot( enc, kDecodeDot );
}
简单推算下