Jam*_*oux 4 c# c++ floating-point encoding glsl
我读过几个讨论在一个浮点数中存储 2 或 3 个浮点数的链接。这是一个例子:
另一个:
还有另一个:
在 glsl 中将 RGB 值解码为单个浮点数,无需进行位移位
我见过其他人,但他们都使用相同的原理。如果要对 x 和 y 进行编码,它们会将 y 乘以某个因子,然后将 x 添加到其中。嗯,这在纸上是这样的,但我不明白当存储为浮点值时它实际上是如何工作的。浮点值只有 7 位有效数字。如果将一个大数和一个小数相加,小数就会被截断并丢失。精度只显示大数的值。
由于每个人似乎都开出相同的方法,我自己尝试了一下,它的效果正是我想象的那样。当我解码这些数字时,未相乘的数字结果为 0.0。它完全丢失在编码的浮动中。
这是我尝试测试的一些 MaxScript 的示例:
cp = 256.0 * 256.0
scaleFac = 16777215
for i = 1 to 20 do (
for j = 1 to 20 do (
x = (i as float / 20.01f) as float;
y = (j as float / 20.01f) as float;
xScaled = x * scaleFac;
yScaled = y * scaleFac;
f = (xScaled + yScaled * cp) as float
print ("x[" + xScaled as string + "] y[" + yScaled as string + "]" + " e[" + f as string + "]")
dy = floor(f / cp)
dx = (f - dy * cp)
print ("x[" + dx as string + "] y[" + dy as string + "]" + " e[" + f as string + "]")
)
)
Run Code Online (Sandbox Code Playgroud)
dx 每次都是 0.0。有人能解释一下吗?注意:无论我设置 cp = 128、256、512 还是其他都没关系。它仍然给我相同类型的结果。
此方法适用于存储两个整数。通过乘以 ,您可以有效地将浮点数转换为大整数scaleFac,这很好,但最好使用 使其显式化int()。然后您需要确保两件事:cp大于您正在使用的最大数字 ( scaleFac),并且 的平方cp足够小以适合浮点数而无需截断(单精度浮点数大约为 7 位数字) 。
下面是C 语言的工作代码,用于将两个floats 打包为一个float并解包。
您应该根据您可能的值范围 ( ) 更改scaleFactor和参数。这是一场精准战。尝试打印一些结果以找到适合您的情况的良好值。下面的示例允许在范围内浮动。cpyourBiggestNumber * scaleFactor < cp[0 to 1)
#include <math.h>
/* yourBiggestNumber * scaleFactor < cp */
double scaleFactor = 65530.0;
double cp = 256.0 * 256.0;
/* packs given two floats into one float */
float pack_float(float x, float y) {
int x1 = (int) (x * scaleFactor);
int y1 = (int) (y * scaleFactor);
float f = (y1 * cp) + x1;
return f;
}
/* unpacks given float to two floats */
int unpack_float(float f, float* x, float* y){
double dy = floor(f / cp);
double dx = f - (dy * cp);
*y = (float) (dy / scaleFactor);
*x = (float) (dx / scaleFactor);
return 0;
}
Run Code Online (Sandbox Code Playgroud)