加载中…
个人资料
则卷大明
则卷大明
  • 博客等级:
  • 博客积分:0
  • 博客访问:7,081
  • 关注人气:2
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

U3D EncodeFloatRGBA&DecodeFloatRGBA

(2014-08-04 17:43:30)
标签:

it

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/(v*255^2)] + [1/(v*255^2)-1/(v*255^4)] + [1/(v*255^4)-1/(v*255^6)] + [1/(v*255^6)-1/(v*255^7)]
=1/v-1/(v*255^7)
这下应该一目了然了,Encode函数是把一个float类型的值存进四个RGBA中,为了提高精度(float值的有效位数只有7位),R值存的是[0, 1/255^2]段的值,G值存的是[1/255^2, 1/255^4]的值,往后依次类推。GBA三个分量分别乘以了255, 255^2,255^3。这样保证其精度落在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.1*r+0.01*g+0.001*b。这个原理其实和上面的Encode和Decode是一样的,只不过这个例子用的是10倍,而U3D中是255倍。

0

阅读 评论 收藏 禁止转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有