|
@@ -5,11 +5,8 @@ import {
|
|
HalfFloatType,
|
|
HalfFloatType,
|
|
LinearEncoding,
|
|
LinearEncoding,
|
|
LinearFilter,
|
|
LinearFilter,
|
|
- NearestFilter,
|
|
|
|
RedFormat,
|
|
RedFormat,
|
|
- RGBAFormat,
|
|
|
|
- RGBEEncoding,
|
|
|
|
- UnsignedByteType
|
|
|
|
|
|
+ RGBAFormat
|
|
} from '../../../build/three.module.js';
|
|
} from '../../../build/three.module.js';
|
|
import * as fflate from '../libs/fflate.module.js';
|
|
import * as fflate from '../libs/fflate.module.js';
|
|
|
|
|
|
@@ -131,41 +128,6 @@ class EXRLoader extends DataTextureLoader {
|
|
|
|
|
|
const logBase = Math.pow( 2.7182818, 2.2 );
|
|
const logBase = Math.pow( 2.7182818, 2.2 );
|
|
|
|
|
|
- var tmpDataView = new DataView( new ArrayBuffer( 8 ) );
|
|
|
|
-
|
|
|
|
- function frexp( value ) {
|
|
|
|
-
|
|
|
|
- if ( value === 0 ) return [ value, 0 ];
|
|
|
|
-
|
|
|
|
- tmpDataView.setFloat64( 0, value );
|
|
|
|
-
|
|
|
|
- var bits = ( tmpDataView.getUint32( 0 ) >>> 20 ) & 0x7FF;
|
|
|
|
- if ( bits === 0 ) { // denormal
|
|
|
|
-
|
|
|
|
- tmpDataView.setFloat64( 0, value * Math.pow( 2, 64 ) ); // exp + 64
|
|
|
|
- bits = ( ( tmpDataView.getUint32( 0 ) >>> 20 ) & 0x7FF ) - 64;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var exponent = bits - 1022;
|
|
|
|
- var mantissa = ldexp( value, - exponent );
|
|
|
|
-
|
|
|
|
- return [ mantissa, exponent ];
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function ldexp( mantissa, exponent ) {
|
|
|
|
-
|
|
|
|
- var steps = Math.min( 3, Math.ceil( Math.abs( exponent ) / 1023 ) );
|
|
|
|
- var result = mantissa;
|
|
|
|
-
|
|
|
|
- for ( var i = 0; i < steps; i ++ )
|
|
|
|
- result *= Math.pow( 2, Math.floor( ( exponent + i ) / steps ) );
|
|
|
|
-
|
|
|
|
- return result;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
function reverseLutFromBitmap( bitmap, lut ) {
|
|
function reverseLutFromBitmap( bitmap, lut ) {
|
|
|
|
|
|
var k = 0;
|
|
var k = 0;
|
|
@@ -2031,18 +1993,18 @@ class EXRLoader extends DataTextureLoader {
|
|
const EXRHeader = {};
|
|
const EXRHeader = {};
|
|
|
|
|
|
if ( dataView.getUint32( 0, true ) != 20000630 ) // magic
|
|
if ( dataView.getUint32( 0, true ) != 20000630 ) // magic
|
|
- throw "THREE.EXRLoader: provided file doesn't appear to be in OpenEXR format.";
|
|
|
|
|
|
+ throw 'THREE.EXRLoader: provided file doesn\'t appear to be in OpenEXR format.';
|
|
|
|
|
|
EXRHeader.version = dataView.getUint8( 4, true );
|
|
EXRHeader.version = dataView.getUint8( 4, true );
|
|
|
|
|
|
const spec = dataView.getUint8( 5, true ); // fullMask
|
|
const spec = dataView.getUint8( 5, true ); // fullMask
|
|
|
|
|
|
EXRHeader.spec = {
|
|
EXRHeader.spec = {
|
|
- singleTile: !!(spec & 1),
|
|
|
|
- longName: !!(spec & 2),
|
|
|
|
- deepFormat: !!(spec & 4),
|
|
|
|
- multiPart: !!(spec & 8),
|
|
|
|
- }
|
|
|
|
|
|
+ singleTile: !! ( spec & 1 ),
|
|
|
|
+ longName: !! ( spec & 2 ),
|
|
|
|
+ deepFormat: !! ( spec & 4 ),
|
|
|
|
+ multiPart: !! ( spec & 8 ),
|
|
|
|
+ };
|
|
|
|
|
|
// start of header
|
|
// start of header
|
|
|
|
|
|
@@ -2076,11 +2038,13 @@ class EXRLoader extends DataTextureLoader {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
if ( spec != 0 ) {
|
|
if ( spec != 0 ) {
|
|
- console.error( "EXRHeader:", EXRHeader );
|
|
|
|
- throw "THREE.EXRLoader: provided file is currently unsupported."
|
|
|
|
|
|
+
|
|
|
|
+ console.error( 'EXRHeader:', EXRHeader );
|
|
|
|
+ throw 'THREE.EXRLoader: provided file is currently unsupported.';
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
return EXRHeader;
|
|
return EXRHeader;
|
|
@@ -2089,7 +2053,7 @@ class EXRLoader extends DataTextureLoader {
|
|
|
|
|
|
function setupDecoder( EXRHeader, dataView, uInt8Array, offset, outputType ) {
|
|
function setupDecoder( EXRHeader, dataView, uInt8Array, offset, outputType ) {
|
|
|
|
|
|
- const EXRDecoder = {
|
|
|
|
|
|
+ const EXRDecoder = {
|
|
size: 0,
|
|
size: 0,
|
|
viewer: dataView,
|
|
viewer: dataView,
|
|
array: uInt8Array,
|
|
array: uInt8Array,
|
|
@@ -2161,7 +2125,6 @@ class EXRLoader extends DataTextureLoader {
|
|
// half
|
|
// half
|
|
switch ( outputType ) {
|
|
switch ( outputType ) {
|
|
|
|
|
|
- case UnsignedByteType:
|
|
|
|
case FloatType:
|
|
case FloatType:
|
|
EXRDecoder.getter = parseFloat16;
|
|
EXRDecoder.getter = parseFloat16;
|
|
EXRDecoder.inputSize = INT16_SIZE;
|
|
EXRDecoder.inputSize = INT16_SIZE;
|
|
@@ -2179,7 +2142,6 @@ class EXRLoader extends DataTextureLoader {
|
|
// float
|
|
// float
|
|
switch ( outputType ) {
|
|
switch ( outputType ) {
|
|
|
|
|
|
- case UnsignedByteType:
|
|
|
|
case FloatType:
|
|
case FloatType:
|
|
EXRDecoder.getter = parseFloat32;
|
|
EXRDecoder.getter = parseFloat32;
|
|
EXRDecoder.inputSize = FLOAT32_SIZE;
|
|
EXRDecoder.inputSize = FLOAT32_SIZE;
|
|
@@ -2200,8 +2162,8 @@ class EXRLoader extends DataTextureLoader {
|
|
EXRDecoder.blockCount = ( EXRHeader.dataWindow.yMax + 1 ) / EXRDecoder.scanlineBlockSize;
|
|
EXRDecoder.blockCount = ( EXRHeader.dataWindow.yMax + 1 ) / EXRDecoder.scanlineBlockSize;
|
|
|
|
|
|
for ( var i = 0; i < EXRDecoder.blockCount; i ++ )
|
|
for ( var i = 0; i < EXRDecoder.blockCount; i ++ )
|
|
- parseInt64( dataView, offset ) // scanlineOffset
|
|
|
|
-
|
|
|
|
|
|
+ parseInt64( dataView, offset ); // scanlineOffset
|
|
|
|
+
|
|
// we should be passed the scanline offset table, ready to start reading pixel data.
|
|
// we should be passed the scanline offset table, ready to start reading pixel data.
|
|
|
|
|
|
// RGB images will be converted to RGBA format, preventing software emulation in select devices.
|
|
// RGB images will be converted to RGBA format, preventing software emulation in select devices.
|
|
@@ -2210,19 +2172,18 @@ class EXRLoader extends DataTextureLoader {
|
|
|
|
|
|
switch ( outputType ) {
|
|
switch ( outputType ) {
|
|
|
|
|
|
- case UnsignedByteType:
|
|
|
|
case FloatType:
|
|
case FloatType:
|
|
EXRDecoder.byteArray = new Float32Array( size );
|
|
EXRDecoder.byteArray = new Float32Array( size );
|
|
|
|
|
|
// Fill initially with 1s for the alpha value if the texture is not RGBA, RGB values will be overwritten
|
|
// Fill initially with 1s for the alpha value if the texture is not RGBA, RGB values will be overwritten
|
|
if ( EXRDecoder.channels < EXRDecoder.outputChannels )
|
|
if ( EXRDecoder.channels < EXRDecoder.outputChannels )
|
|
- EXRDecoder.byteArray.fill( 1, 0, size );
|
|
|
|
-
|
|
|
|
|
|
+ EXRDecoder.byteArray.fill( 1, 0, size );
|
|
|
|
+
|
|
break;
|
|
break;
|
|
|
|
|
|
case HalfFloatType:
|
|
case HalfFloatType:
|
|
EXRDecoder.byteArray = new Uint16Array( size );
|
|
EXRDecoder.byteArray = new Uint16Array( size );
|
|
-
|
|
|
|
|
|
+
|
|
if ( EXRDecoder.channels < EXRDecoder.outputChannels )
|
|
if ( EXRDecoder.channels < EXRDecoder.outputChannels )
|
|
EXRDecoder.byteArray.fill( 0x3C00, 0, size ); // Uint16Array holds half float data, 0x3C00 is 1
|
|
EXRDecoder.byteArray.fill( 0x3C00, 0, size ); // Uint16Array holds half float data, 0x3C00 is 1
|
|
|
|
|
|
@@ -2237,11 +2198,15 @@ class EXRLoader extends DataTextureLoader {
|
|
EXRDecoder.bytesPerLine = EXRDecoder.width * EXRDecoder.inputSize * EXRDecoder.channels;
|
|
EXRDecoder.bytesPerLine = EXRDecoder.width * EXRDecoder.inputSize * EXRDecoder.channels;
|
|
|
|
|
|
if ( EXRDecoder.outputChannels == 4 ) {
|
|
if ( EXRDecoder.outputChannels == 4 ) {
|
|
|
|
+
|
|
EXRDecoder.format = RGBAFormat;
|
|
EXRDecoder.format = RGBAFormat;
|
|
- EXRDecoder.encoding = ( outputType == UnsignedByteType ) ? RGBEEncoding : LinearEncoding;
|
|
|
|
|
|
+ EXRDecoder.encoding = LinearEncoding;
|
|
|
|
+
|
|
} else {
|
|
} else {
|
|
|
|
+
|
|
EXRDecoder.format = RedFormat;
|
|
EXRDecoder.format = RedFormat;
|
|
EXRDecoder.encoding = LinearEncoding;
|
|
EXRDecoder.encoding = LinearEncoding;
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
return EXRDecoder;
|
|
return EXRDecoder;
|
|
@@ -2264,10 +2229,10 @@ class EXRLoader extends DataTextureLoader {
|
|
const channelOffsets = { R: 0, G: 1, B: 2, A: 3, Y: 0 };
|
|
const channelOffsets = { R: 0, G: 1, B: 2, A: 3, Y: 0 };
|
|
|
|
|
|
for ( let scanlineBlockIdx = 0; scanlineBlockIdx < EXRDecoder.height / EXRDecoder.scanlineBlockSize; scanlineBlockIdx ++ ) {
|
|
for ( let scanlineBlockIdx = 0; scanlineBlockIdx < EXRDecoder.height / EXRDecoder.scanlineBlockSize; scanlineBlockIdx ++ ) {
|
|
-
|
|
|
|
|
|
+
|
|
const line = parseUint32( bufferDataView, offset ); // line_no
|
|
const line = parseUint32( bufferDataView, offset ); // line_no
|
|
EXRDecoder.size = parseUint32( bufferDataView, offset ); // data_len
|
|
EXRDecoder.size = parseUint32( bufferDataView, offset ); // data_len
|
|
- EXRDecoder.lines = ( ( line + EXRDecoder.scanlineBlockSize > EXRDecoder.height ) ? (EXRDecoder.height-line) : EXRDecoder.scanlineBlockSize );
|
|
|
|
|
|
+ EXRDecoder.lines = ( ( line + EXRDecoder.scanlineBlockSize > EXRDecoder.height ) ? ( EXRDecoder.height - line ) : EXRDecoder.scanlineBlockSize );
|
|
|
|
|
|
const isCompressed = EXRDecoder.size < EXRDecoder.lines * EXRDecoder.bytesPerLine;
|
|
const isCompressed = EXRDecoder.size < EXRDecoder.lines * EXRDecoder.bytesPerLine;
|
|
const viewer = isCompressed ? EXRDecoder.uncompress( EXRDecoder ) : uncompressRAW( EXRDecoder );
|
|
const viewer = isCompressed ? EXRDecoder.uncompress( EXRDecoder ) : uncompressRAW( EXRDecoder );
|
|
@@ -2297,47 +2262,6 @@ class EXRLoader extends DataTextureLoader {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- // convert to RGBE if user specifies Uint8 output on a RGB input texture
|
|
|
|
- if ( EXRDecoder.encoding == RGBEEncoding ) {
|
|
|
|
-
|
|
|
|
- let v, i;
|
|
|
|
- const size = EXRDecoder.byteArray.length;
|
|
|
|
- const RGBEArray = new Uint8Array( size );
|
|
|
|
-
|
|
|
|
- for ( let h = 0; h < EXRDecoder.height; ++ h ) {
|
|
|
|
-
|
|
|
|
- for ( let w = 0; w < EXRDecoder.width; ++ w ) {
|
|
|
|
-
|
|
|
|
- i = h * EXRDecoder.width * 4 + w * 4;
|
|
|
|
- const red = EXRDecoder.byteArray[ i ];
|
|
|
|
- const green = EXRDecoder.byteArray[ i + 1 ];
|
|
|
|
- const blue = EXRDecoder.byteArray[ i + 2 ];
|
|
|
|
- v = red > green ? red : green;
|
|
|
|
- v = blue > v ? blue : v;
|
|
|
|
-
|
|
|
|
- if ( v < 1e-32 ) {
|
|
|
|
-
|
|
|
|
- RGBEArray[ i ] = RGBEArray[ i + 1 ] = RGBEArray[ i + 2 ] = RGBEArray[ i + 3 ] = 0;
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- const res = frexp( v );
|
|
|
|
- v = res[ 0 ] * 256 / v;
|
|
|
|
- RGBEArray[ i ] = red * v;
|
|
|
|
- RGBEArray[ i + 1 ] = green * v;
|
|
|
|
- RGBEArray[ i + 2 ] = blue * v;
|
|
|
|
- RGBEArray[ i + 3 ] = res[ 1 ] + 128;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- EXRDecoder.byteArray = RGBEArray;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
return {
|
|
return {
|
|
header: EXRHeader,
|
|
header: EXRHeader,
|
|
width: EXRDecoder.width,
|
|
width: EXRDecoder.width,
|
|
@@ -2362,8 +2286,8 @@ class EXRLoader extends DataTextureLoader {
|
|
function onLoadCallback( texture, texData ) {
|
|
function onLoadCallback( texture, texData ) {
|
|
|
|
|
|
texture.encoding = texData.encoding;
|
|
texture.encoding = texData.encoding;
|
|
- texture.minFilter = ( texture.encoding == RGBEEncoding ) ? NearestFilter : LinearFilter;
|
|
|
|
- texture.magFilter = ( texture.encoding == RGBEEncoding ) ? NearestFilter : LinearFilter;
|
|
|
|
|
|
+ texture.minFilter = LinearFilter;
|
|
|
|
+ texture.magFilter = LinearFilter;
|
|
texture.generateMipmaps = false;
|
|
texture.generateMipmaps = false;
|
|
texture.flipY = false;
|
|
texture.flipY = false;
|
|
|
|
|