|
@@ -1,7 +1,7 @@
|
|
|
import {
|
|
|
ClampToEdgeWrapping,
|
|
|
DataTexture,
|
|
|
- FloatType,
|
|
|
+ HalfFloatType,
|
|
|
LinearFilter,
|
|
|
NearestFilter,
|
|
|
RGBAFormat,
|
|
@@ -25,6 +25,59 @@ import {
|
|
|
// by Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt
|
|
|
// code: https://github.com/selfshadow/ltc_code/
|
|
|
|
|
|
+// Convert float32 array value to float16 stored in uint16 array value.
|
|
|
+// Source: http://gamedev.stackexchange.com/questions/17326/conversion-of-a-number-from-single-precision-floating-point-representation-to-a/17410#17410
|
|
|
+
|
|
|
+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. */
|
|
|
+
|
|
|
+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 RectAreaLightUniformsLib = {
|
|
|
|
|
|
init: function () {
|
|
@@ -37,8 +90,18 @@ var RectAreaLightUniformsLib = {
|
|
|
|
|
|
// data textures
|
|
|
|
|
|
- var ltc_1 = new DataTexture( new Float32Array( LTC_MAT_1 ), 64, 64, RGBAFormat, FloatType, UVMapping, ClampToEdgeWrapping, ClampToEdgeWrapping, LinearFilter, NearestFilter, 1 );
|
|
|
- var ltc_2 = new DataTexture( new Float32Array( LTC_MAT_2 ), 64, 64, RGBAFormat, FloatType, UVMapping, ClampToEdgeWrapping, ClampToEdgeWrapping, LinearFilter, NearestFilter, 1 );
|
|
|
+ const LTC_MAT_HALF_1 = new Uint16Array(LTC_MAT_1.length);
|
|
|
+ LTC_MAT_1.forEach(function(x, index) {
|
|
|
+ LTC_MAT_HALF_1[index] = toHalf(x);
|
|
|
+ });
|
|
|
+
|
|
|
+ const LTC_MAT_HALF_2 = new Uint16Array(LTC_MAT_2.length);
|
|
|
+ LTC_MAT_2.forEach(function(x, index) {
|
|
|
+ LTC_MAT_HALF_2[index] = toHalf(x);
|
|
|
+ });
|
|
|
+
|
|
|
+ var ltc_1 = new DataTexture( LTC_MAT_HALF_1, 64, 64, RGBAFormat, HalfFloatType, UVMapping, ClampToEdgeWrapping, ClampToEdgeWrapping, LinearFilter, NearestFilter, 1 );
|
|
|
+ var ltc_2 = new DataTexture( LTC_MAT_HALF_2, 64, 64, RGBAFormat, HalfFloatType, UVMapping, ClampToEdgeWrapping, ClampToEdgeWrapping, LinearFilter, NearestFilter, 1 );
|
|
|
|
|
|
UniformsLib.LTC_1 = ltc_1;
|
|
|
UniformsLib.LTC_2 = ltc_2;
|