-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
127 additions
and
76 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
|
||
// ref: http://stackoverflow.com/questions/32633585/how-do-you-convert-to-half-floats-in-javascript | ||
function toHalf(value) { | ||
const floatView = new Float32Array(1); | ||
const 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. | ||
|
||
floatView[0] = value; | ||
const x = int32View[0]; | ||
|
||
let bits = (x >> 16) & 0x8000; // Get the sign | ||
let m = (x >> 12) & 0x07ff; // Keep one extra bit for rounding | ||
const 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; | ||
} | ||
|
||
// ref: https://stackoverflow.com/questions/5678432/decompressing-half-precision-floats-in-javascript | ||
function fromHalf(h) { | ||
const s = (h & 0x8000) >> 15 ? -1 : 1; | ||
const e = (h & 0x7C00) >> 10; | ||
const f = h & 0x03FF; | ||
|
||
if (e == 0) { | ||
return s * Math.pow(2, -14) * (f / Math.pow(2, 10)); | ||
} else if (e == 0x1F) { | ||
return f ? NaN : (s * Infinity); | ||
} | ||
|
||
return s * Math.pow(2, e - 15) * (1 + (f / Math.pow(2, 10))); | ||
} |
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
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