【发布时间】:2016-05-03 07:25:13
【问题描述】:
我在 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 的值不合理。事实上,这在一种硬件中运行良好,而在另一种硬件中运行不佳。
我想知道量化(也是 inv-quantize)浮点值的好方法。
【问题讨论】:
-
定义“效果不佳”。另外,您允许使用哪些版本的 OpenGL?
-
表示“没有量化好”;如果我将浮点
f转换为 inteferb并再次转换为f',则错误f-f'很大。我使用 OpenGL 2.0(也是 OpenGL ES 2.0)。 -
多大?误差是否大到不合理?发布实际数字。
-
在 GLSL 中获取纹理像素的实际值非常困难。但是,它可以说是我可以“看到”错误的最大程度。假设我要压缩要解压缩的图像数据。解压后得到相同的图像是理想的,但不可能,因为这些过程需要量化和逆量化。如果图像变得有些退化,这是一个小错误。但是,如果图像的白色像素变成绿色像素,那就是一个很大的错误,我可以“看到”。
-
"在 GLSL 中获取纹理像素的实际值非常困难。" 你使用
glGetTexImage。下载纹素数据与上传并没有什么不同。
标签: c++ opengl floating-point glsl