我试图优化纹理内存,所有阻止我将GL_RGBA32F LUT转换为GL_RGBA16F的是一个(可能)超过限制的索引。无论如何,我可以在C中取一个浮点数并将其拆分为2个值,然后在GLSL重构中从存储在LUT中的2个值中浮动?
我的意思是这样的:
[C]
float v0,v1, *pixel_array;
magic_function_in_c( my_big_value, &v0, &v1 );
pixel_array[ index++ ] = pos.x; // R
pixel_array[ index++ ] = pos.y; // G
pixel_array[ index++ ] = v0; // B
pixel_array[ index++ ] = v1; // A
[GLSL]
vec4 lookup = texture2D( sampler0, texcoord );
float v = magic_function_in_glsl( lookup.b, lookup.a );
ps:我正在使用GLES 2.0(也与WebGL兼容)
答案 0 :(得分:1)
如果你只需要比float16提供更多的范围,并且只需要在一个方向(更大或更小),你可以乘以一个固定的比例因子。
例如,如果您需要某个数字N,大于65503,则可以编码'将N除以2,然后解码'乘以2.这使有效范围向上移动,牺牲1 / N的范围,但扩大+/- N的范围最大值。如果您需要更多的1 / N范围而不是+/- N,则可以交换乘法和除法。如果需要根据数据进行更改,可以使用第二个值来存储缩放因子。
您还可以尝试使用exp2和log2,例如:
void
magic_function_in_c(float fVal, uint16_t* hExponent, uint16_t* hMult)
{
float fExponent = log2f(f);
*hExponent = f32_to_f16(fExponent);
// Compensate for f32->f16 precision loss
float fActualExponent = f16_to_f32(*hExponent);
float fValFromExponent = exp2f(fActualExponent);
float fMult;
if (fValFromExponent != 0.0f) {
fMult = fVal / fValFromExponent;
} else if (fVal < 0.0f) {
fMult = -1.0f;
} else {
fMult = 1.0f
}
*hMult = f32_to_f16(fMult);
}
highp float
magic_function_in_glsl(highp float hExponent, highp float hMult)
{
return exp2(hExponent) * hMult;
}
请注意,如果您的GLSL着色器中没有highp浮点数,则这些都不会起作用。