Last active
December 8, 2018 06:25
-
-
Save zeux/a47210f82406e760f7971f136c3d0c82 to your computer and use it in GitHub Desktop.
8-bit (unsigned) floating point encoding that is designed to be very efficient to decode on DX9/GLES2 class GPUs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Can be used to efficiently encode floating point values from a limited range ([0..65k]) into a byte | |
// edgeDecode is optimized for GPUs (native exp2) | |
// edgeEncode1 is optimized for GPUs (native log2) | |
// edgeEncode2 is optimized for CPUs but is an approximation | |
// edgeEncode3 is optimized for CPUs | |
float edgeDecode(int e) | |
{ | |
return exp2f(float(e) * (1 / 16.f)) - 1; | |
} | |
// max relative error 4.3% on [1, 2048] range | |
int edgeEncode1(float f) | |
{ | |
return log2f(f + 1) * 16 + 0.5f; | |
} | |
// max relative error 12% on [1, 2048] range | |
int edgeEncode2(float f) | |
{ | |
// This is an approximation of log2(f + 1) * 16 + 0.5 | |
// Instead of computing log2 precisely, we compute integer part by taking the floating point exponent | |
// and take the fractional part as is (rounded) | |
union { float f; uint32_t ui; } u; | |
u.f = f + 1; | |
uint32_t v = u.ui; | |
return (v - (127 << 23) + (1 << 18)) >> 19; | |
} | |
// precompute this table with: | |
// for (size_t i = 0; i < 128; ++i) edgeEncode3Table[i] = int(log2f(1 + float(i) / 128) * 16 + 0.5f); | |
uint8_t edgeEncode3Table[128]; | |
// max relative error 4.5% on [1, 2048] range | |
int edgeEncode3(float f) | |
{ | |
// This is an approximation of log2(f + 1) * 16 + 0.5 that refines edgeEncode2 with a table lookup | |
union { float f; uint32_t ui; } u; | |
u.f = f + 1; | |
uint32_t v = u.ui; | |
return (((v >> 23) - 127) << 4) + edgeEncode3Table[(v >> 16) & 127]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment