U3D EncodeFloatRGBA&DecodeFloatRGBA

转自:http://blog.sina.com.cn/s/blog_70f96aa90102v0t7.html
U3D EncodeFloatRGBA&DecodeFloatRGBA

UnityCG.cginc中的原函数代码如下:

inline float4 EncodeFloatRGBA( float v )
{
	float4 kEncodeMul = float4(1.0, 255.0, 65025.0, 160581375.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/160581375.0);
	return dot( enc, kDecodeDot );
}

单单看代码实在让人摸不着头脑,展开后可得EncodeFloatRGBA的最终结果为:

x = 1/v - 1/(v*255^2);			//R
y = 1/(v*255) - 1/(v*255^3);	//G
z = 1/(v*255^2) - 1/(v*255^4);	//B
w = 1/(v*255^3) - 1/(v*255^4);	//A

感觉抓到了一点东西,但是还是不是很清楚,再看Decode函数计算结果:

[1/v-1/(v255^2)] + [1/(v2552)-1/(v*2554)] + [1/(v2554)-1/(v*2556)] + [1/(v2556)-1/(v*2557)]
=1/v-1/(v*255^7)

这下应该一目了然了,Encode函数是把一个float类型的值存进四个RGBA中,为了提高精度(float值的有效位数只有7位),R值存的是[0, 1/2552]段的值,G值存的是[1/2552, 1/255^4]的值,往后依次类推。GBA三个分量分别乘以了255, 2552,2553。这样保证其精度落在float类型的有效位数内。至于1/255^7后面的数值,则基本可以忽略不计了,而且float也存不下了。

说的再简单一点,举个例子,比如现在有个float类型的值h=1.23456…,我如果把h存在一个int整形的变量里面,那么小数后面的精度肯定丢失了。如果我想保留,那么可以用四个整形变量a, r, g, b来保存,a = 1, r = 2, g = 3, b = 4。这样g可以表示为:h = a+0.1r+0.01g+0.001*b。这个原理其实和上面的Encode和Decode是一样的,只不过这个例子用的是10倍,而U3D中是255倍。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值