森建 (2017-04-09T14:56:46.000Z)
moriken at kimamass.com (2017-04-09T15:12:34.416Z)
WebGL 2.0 supports half-precision float (16bit float) by default. But now, we must use the following dirty hack using `Uint16Array`. ```js // ref: http://stackoverflow.com/questions/32633585/how-do-you-convert-to-half-floats-in-javascript var toHalf = (function() { var floatView = new Float32Array(1); var int32View = new Int32Array(floatView.buffer); /* This method is faster than the OpenEXR implementation (very often * used, eg. in Ogre), with the additional benefit of rounding, inspired * by James Tursa?s half-precision code. */ return function toHalf(val) { floatView[0] = val; var x = int32View[0]; var bits = (x >> 16) & 0x8000; /* Get the sign */ var m = (x >> 12) & 0x07ff; /* Keep one extra bit for rounding */ var e = (x >> 23) & 0xff; /* Using int is faster here */ /* If zero, or denormal, or exponent underflows too much for a denormal * half, return signed zero. */ if (e < 103) { return bits; } /* If NaN, return NaN. If Inf or exponent overflow, return Inf. */ if (e > 142) { bits |= 0x7c00; /* If exponent was 0xff and one mantissa bit was set, it means NaN, * not Inf, so make sure we set one mantissa bit too. */ bits |= ((e == 255) ? 0 : 1) && (x & 0x007fffff); return bits; } /* If exponent underflows but not too much, return a denormal */ if (e < 113) { m |= 0x0800; /* Extra rounding may overflow and set mantissa to 0 and exponent * to 1, which is OK. */ bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1); return bits; } bits |= ((e - 112) << 10) | (m >> 1); /* Extra rounding. An overflow will set mantissa to 0 and increment * the exponent, which is OK. */ bits += m & 1; return bits; }; }()); var tex = new Uint16Array(4); tex[0] = toHalf(0.5); tex[1] = toHalf(1); tex[2] = toHalf(123); tex[3] = toHalf(-13); ``` The time has come. https://en.wikipedia.org/wiki/Half-precision_floating-point_format
moriken at kimamass.com (2017-04-09T15:02:50.499Z)
WebGL 2.0 supports half-precision float (16bit float) by default. But now, we must use the following dirty hack using `Uint16Array`. ```js // ref: http://stackoverflow.com/questions/32633585/how-do-you-convert-to-half-floats-in-javascript var toHalf = (function() { var floatView = new Float32Array(1); var int32View = new Int32Array(floatView.buffer); /* This method is faster than the OpenEXR implementation (very often * used, eg. in Ogre), with the additional benefit of rounding, inspired * by James Tursa?s half-precision code. */ return function toHalf(val) { floatView[0] = val; var x = int32View[0]; var bits = (x >> 16) & 0x8000; /* Get the sign */ var m = (x >> 12) & 0x07ff; /* Keep one extra bit for rounding */ var e = (x >> 23) & 0xff; /* Using int is faster here */ /* If zero, or denormal, or exponent underflows too much for a denormal * half, return signed zero. */ if (e < 103) { return bits; } /* If NaN, return NaN. If Inf or exponent overflow, return Inf. */ if (e > 142) { bits |= 0x7c00; /* If exponent was 0xff and one mantissa bit was set, it means NaN, * not Inf, so make sure we set one mantissa bit too. */ bits |= ((e == 255) ? 0 : 1) && (x & 0x007fffff); return bits; } /* If exponent underflows but not too much, return a denormal */ if (e < 113) { m |= 0x0800; /* Extra rounding may overflow and set mantissa to 0 and exponent * to 1, which is OK. */ bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1); return bits; } bits |= ((e - 112) << 10) | (m >> 1); /* Extra rounding. An overflow will set mantissa to 0 and increment * the exponent, which is OK. */ bits += m & 1; return bits; }; }()); var tex = new Uint16Array(4); tex[0] = toHalf(0.5); tex[1] = toHalf(1); tex[2] = toHalf(123); tex[3] = toHalf(-13); ``` The time has come. https://en.wikipedia.org/wiki/Half-precision_floating-point_format