我在GLSL中使用浮点纹理作为数据缓冲区,需要将数据保存在普通纹理上(每个像素的颜色有1个字节)。在我的情况下,浮点是[-2048.0,2048.0],因此我必须将[-2048.0,2048.0]量化为[0,255]。我认为这个问题的C ++代码就像:
//*quantization*
float fvalue = ... ; // floating point data
fvalue /= 16.0f; // [-128.0, 128.0]
fvalue = roundf(fvalue); // [-128, 128]
if(fvalue > 127.0f) fvalue = 127.0f;
else if(fvalue < -128.0f) fvalue = -128.0f;
u_char byte = (int)fvalue + 128; // [0, 255]
//*inverse quantization*
u_char byte = ...; // [0, 255]
float fvalue = byte - 128; // [-128, 127]
fvalue *= 16.0f; // [-2048, 2032] (it can't be helped?)
我不确定这段代码是否合适,但我还不确定GLSL中有什么好处(GLSL将字节值[0,255]作为浮点[0.0,1.0]处理)。我的代码是:
//*quantization*
vec3 F = ...; //F is floating vector [-2048.0, 2048.0]
F /= 16; // [-128.0, 128.0]
F /= 256; // [-0.5, 0.5]
F += vec3(0.50f); // [0.0, 1.0]
gl_FragData[0] = vec4(F, 1.0);
//*inverse quantization*
vec3 F = texture2D(...); //byte data [0.0, 1.0]
F -= vec3(0.50f); //byte data [-0.5, 0.5]
F *= 256; //[-128, 128]
F *= 16; //[-2048, 2048]
这并没有奏效。但是,如果我将代码F += vec3(0.50f);
重写为F += vec3(0.51f);
,又将F -= vec3(0.50f);
重写为F -= vec3(0.51f);
,那么它似乎运作良好。但我不认为价值0.51f
是合理的。实际上,这在一个硬件中运行良好,而这在另一个硬件中不能很好地工作。
我想知道量化(也是量子化)浮点值的好方法。
答案 0 :(得分:1)
我可以找到适用的方式&#34;以及#34;。我不敢说我无法合理解释为什么它有效,所以我不知道这是否是多功能方法。
dialog.setCancelable(false);
答案 1 :(得分:1)
首先,每个具有1个字节的像素不能充分传达您想要描述的内容。这种所谓的“正常纹理”更准确地称为“无符号标准化”(通常缩写为unorm
)。
你想要一个8位的unorm纹理(理想情况下有多个组件);这些是存储定点数据的纹理,当通过将数据标准化为其固有范围进行采样时,将其视为浮点(在[ 0.0 , 1.0 ]范围内) (例如升级到浮点并除以 255.0 )。
鉴于刚刚描述的内容,您只需将原始数据[ -2048.0 , 2048.0 ]转换为[ 0.0 , 1.0 ]然后乘以 255 。
但这是不太理想的,因为您将无法在没有严重混叠的情况下表示原始范围。相反,乘以 4294967295 ( 256 4 - 1 )并将8位打包成R,8位到G,8位到B和8位到A。你没有尝试在显示的着色器中打包组件。