理解EncodeFloatRGBA与DecodeFloatRGBA

作者:追风剑情 发布于:2018-7-11 18:39 分类:Shader

以下是对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 );
}

简单推算下

11111.jpg

标签: Shader

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号