Browse Source

(three.js issue: #5552) add BinaryTextireLoader.js, RGBELoader.js (plus example), TGALoader.js extends BinaryTextureLoader.js

Nikos M 10 years ago
parent
commit
5cee8deca6

+ 303 - 0
examples/js/loaders/RGBELoader.js

@@ -0,0 +1,303 @@
+/**
+ * @author Nikos M. / https://github.com/foo123/
+ */
+
+// https://github.com/mrdoob/three.js/issues/5552
+// http://en.wikipedia.org/wiki/RGBE_image_format
+
+THREE.HDRLoader = THREE.RGBELoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+
+};
+
+// extend THREE.BinaryTextureLoader
+THREE.RGBELoader.prototype = Object.create( THREE.BinaryTextureLoader.prototype );
+
+// adapted from http://www.graphics.cornell.edu/~bjw/rgbe.html
+THREE.RGBELoader.prototype._parser = function( buffer ) {
+
+	var
+		/* return codes for rgbe routines */
+		RGBE_RETURN_SUCCESS =  0,
+		RGBE_RETURN_FAILURE = -1,
+
+		/* default error routine.  change this to change error handling */
+		rgbe_read_error     = 1,
+		rgbe_write_error    = 2,
+		rgbe_format_error   = 3,
+		rgbe_memory_error   = 4,
+		rgbe_error = function(rgbe_error_code, msg) {
+			switch (rgbe_error_code) {
+				case rgbe_read_error: console.error("THREE.RGBELoader Read Error: " + (msg||''));
+				break;
+				case rgbe_write_error: console.error("THREE.RGBELoader Write Error: " + (msg||''));
+				break;
+				case rgbe_format_error:  console.error("THREE.RGBELoader Bad File Format: " + (msg||''));
+				break;
+				default:
+				case rgbe_memory_error:  console.error("THREE.RGBELoader: Error: " + (msg||''));
+			}
+			return RGBE_RETURN_FAILURE;
+		},
+
+		/* offsets to red, green, and blue components in a data (float) pixel */
+		RGBE_DATA_RED      = 0,
+		RGBE_DATA_GREEN    = 1,
+		RGBE_DATA_BLUE     = 2,
+
+		/* number of floats per pixel, use 4 since stored in rgba image format */
+		RGBE_DATA_SIZE     = 4,
+
+		/* flags indicating which fields in an rgbe_header_info are valid */
+		RGBE_VALID_PROGRAMTYPE      = 1,
+		RGBE_VALID_FORMAT           = 2,
+		RGBE_VALID_DIMENSIONS       = 4,
+
+		NEWLINE = "\n",
+
+		fgets = function( buffer, lineLimit, consume ) {
+			lineLimit = !lineLimit ? 1024 : lineLimit;
+			var p = buffer.pos,
+				i = -1, len = 0, s = '', chunkSize = 128,
+				chunk = String.fromCharCode.apply(null, new Uint16Array( buffer.subarray( p, p+chunkSize ) ) )
+			;
+			while ( (0 > (i=chunk.indexOf( NEWLINE ))) && (len < lineLimit) && (p < buffer.byteLength) ) {
+
+				s += chunk; len += chunk.length;
+				p += chunkSize;
+				chunk += String.fromCharCode.apply(null, new Uint16Array( buffer.subarray( p, p+chunkSize ) ) );
+
+			}
+
+			if ( -1 < i ) {
+
+				/*for (i=l-1; i>=0; i--) {
+					byteCode = m.charCodeAt(i);
+					if (byteCode > 0x7f && byteCode <= 0x7ff) byteLen++;
+					else if (byteCode > 0x7ff && byteCode <= 0xffff) byteLen += 2;
+					if (byteCode >= 0xDC00 && byteCode <= 0xDFFF) i--; //trail surrogate
+				}*/
+				if ( false !== consume ) buffer.pos += len+i+1;
+				return s + chunk.slice(0, i);
+
+			}
+			return false;
+		},
+
+		/* minimal header reading.  modify if you want to parse more information */
+		RGBE_ReadHeader = function( buffer ) {
+			var line, match,
+
+				// regexes to parse header info fields
+				magic_token_re = /^#\?(\S+)$/,
+				gamma_re = /^\s*GAMMA\s*=\s*(\d+(\.\d+)?)\s*$/,
+				exposure_re = /^\s*EXPOSURE\s*=\s*(\d+(\.\d+)?)\s*$/,
+				format_re = /^\s*FORMAT=(\S+)\s*$/,
+				dimensions_re = /^\s*\-Y\s+(\d+)\s+\+X\s+(\d+)\s*$/,
+
+				// RGBE format header struct
+				header = {
+
+				  valid: 0,                         /* indicate which fields are valid */
+
+				  string: '',                       /* the actual header string */
+
+				  comments: '',                     /* comments found in header */
+
+				  programtype: 'RGBE',              /* listed at beginning of file to identify it
+													* after "#?".  defaults to "RGBE" */
+
+				  format: '',                       /* RGBE format, default 32-bit_rle_rgbe */
+
+				  gamma: 1.0,                       /* image has already been gamma corrected with
+													* given gamma.  defaults to 1.0 (no correction) */
+
+				  exposure: 1.0,                    /* a value of 1.0 in an image corresponds to
+													* <exposure> watts/steradian/m^2.
+													* defaults to 1.0 */
+
+				  width: 0, height: 0               /* image dimensions, width/height */
+
+				}
+			;
+
+			if ( buffer.pos >= buffer.byteLength || !( line=fgets( buffer ) ) ) {
+				return rgbe_error( rgbe_read_error, "no header found" );
+			}
+			/* if you want to require the magic token then uncomment the next line */
+			if ( !(match=line.match(magic_token_re)) ) {
+				return rgbe_error( rgbe_format_error, "bad initial token" );
+			}
+			header.valid |= RGBE_VALID_PROGRAMTYPE;
+			header.programtype = match[1];
+			header.string += line + "\n";
+
+			while ( true ) {
+
+				line = fgets( buffer );
+				if ( false === line ) break;
+				header.string += line + "\n";
+
+				if ( '#' === line.charAt(0) ) {
+					header.comments += line + "\n";
+					continue; // comment line
+				}
+
+				if ( match=line.match(gamma_re) ) {
+					header.gamma = parseFloat(match[1], 10);
+				}
+				if ( match=line.match(exposure_re) ) {
+					header.exposure = parseFloat(match[1], 10);
+				}
+				if ( match=line.match(format_re) ) {
+					header.valid |= RGBE_VALID_FORMAT;
+					header.format = match[1];//'32-bit_rle_rgbe';
+				}
+				if ( match=line.match(dimensions_re) ) {
+					header.valid |= RGBE_VALID_DIMENSIONS;
+					header.height = parseInt(match[1], 10);
+					header.width = parseInt(match[2], 10);
+				}
+
+				if ( (header.valid&RGBE_VALID_FORMAT) && (header.valid&RGBE_VALID_DIMENSIONS) ) break;
+			}
+
+			if ( !(header.valid&RGBE_VALID_FORMAT) ) {
+				return rgbe_error( rgbe_format_error, "missing format specifier" );
+			}
+			if ( !(header.valid&RGBE_VALID_DIMENSIONS) ) {
+				return rgbe_error( rgbe_format_error, "missing image size specifier" );
+			}
+
+			return header;
+		},
+
+		RGBE_ReadPixels_RLE = function( buffer, w, h ) {
+			var data_rgba, offset, pos, count, byteValue,
+				scanline_buffer, ptr, ptr_end, i, l, off, isEncodedRun,
+				scanline_width = w, num_scanlines = h, rgbeStart
+			;
+
+			if (
+				// run length encoding is not allowed so read flat
+				((scanline_width < 8) || (scanline_width > 0x7fff)) ||
+				// this file is not run length encoded
+				((2 !== buffer[0]) || (2 !== buffer[1]) || (buffer[2] & 0x80))
+			) {
+				// return the flat buffer
+				return new Uint8Array( buffer );
+			}
+
+			if ( scanline_width !== ((buffer[2]<<8) | buffer[3]) ) {
+				return rgbe_error(rgbe_format_error, "wrong scanline width");
+			}
+
+			data_rgba = new Uint8Array( 4*w*h );
+
+			if ( !data_rgba || !data_rgba.length ) {
+				return rgbe_error(rgbe_memory_error, "unable to allocate buffer space");
+			}
+
+			offset = 0; pos = 0; ptr_end = 4*scanline_width;
+			rgbeStart = new Uint8Array( 4 );
+			scanline_buffer = new Uint8Array( ptr_end );
+
+			// read in each successive scanline
+			while( (num_scanlines > 0) && (pos < buffer.byteLength) ) {
+
+				if ( pos+4 > buffer.byteLength ) {
+
+					return rgbe_error( rgbe_read_error );
+
+				}
+
+				rgbeStart[0] = buffer[pos++];
+				rgbeStart[1] = buffer[pos++];
+				rgbeStart[2] = buffer[pos++];
+				rgbeStart[3] = buffer[pos++];
+
+				if ( (2 != rgbeStart[0]) || (2 != rgbeStart[1]) || (((rgbeStart[2]<<8) | rgbeStart[3]) != scanline_width) ) {
+
+					return rgbe_error(rgbe_format_error, "bad rgbe scanline format");
+
+				}
+
+				// read each of the four channels for the scanline into the buffer
+				// first red, then green, then blue, then exponent
+				ptr = 0;
+				while ( (ptr < ptr_end) && (pos < buffer.byteLength) ) {
+
+					count = buffer[ pos++ ];
+					isEncodedRun = count > 128;
+					if ( isEncodedRun ) count -= 128;
+
+					if ( (0 === count) || (ptr+count > ptr_end) ) {
+
+						return rgbe_error(rgbe_format_error, "bad scanline data");
+
+					}
+
+					if ( isEncodedRun ) {
+						// a (encoded) run of the same value
+						byteValue = buffer[ pos++ ];
+						for (i=0; i<count; i++) {
+							scanline_buffer[ ptr++ ] = byteValue;
+						}
+						//ptr += count;
+
+					} else {
+						// a literal-run
+						scanline_buffer.set( buffer.subarray(pos, pos+count), ptr );
+						ptr += count; pos += count;
+					}
+				}
+
+
+				// now convert data from buffer into rgba
+				// first red, then green, then blue, then exponent (alpha)
+				l = scanline_width; //scanline_buffer.byteLength;
+				for (i=0; i<l; i++) {
+					off = 0;
+					data_rgba[offset] = scanline_buffer[i+off];
+					off += scanline_width; //1;
+					data_rgba[offset+1] = scanline_buffer[i+off];
+					off += scanline_width; //1;
+					data_rgba[offset+2] = scanline_buffer[i+off];
+					off += scanline_width; //1;
+					data_rgba[offset+3] = scanline_buffer[i+off];
+					offset += 4;
+				}
+
+				num_scanlines--;
+			}
+
+			return data_rgba;
+		}
+	;
+
+	var byteArray = new Uint8Array( buffer ),
+		byteLength = byteArray.byteLength;
+	byteArray.pos = 0;
+	var rgbe_header_info = RGBE_ReadHeader( byteArray );
+
+	if ( RGBE_RETURN_FAILURE !== rgbe_header_info ) {
+
+		var w = rgbe_header_info.width,
+			h = rgbe_header_info.height
+			,image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray(byteArray.pos), w, h )
+		;
+		if ( RGBE_RETURN_FAILURE !== image_rgba_data ) {
+			return {
+				width: w, height: h,
+				data: image_rgba_data,
+				header: rgbe_header_info.string,
+				gamma: rgbe_header_info.gamma,
+				exposure: rgbe_header_info.exposure,
+				format: THREE.RGBEFormat, // handled as THREE.RGBAFormat in shaders
+				type: THREE.UnsignedByteType
+			};
+		}
+	}
+	return null;
+};

+ 327 - 351
examples/js/loaders/TGALoader.js

@@ -9,447 +9,423 @@ THREE.TGALoader = function ( manager ) {
 
 
 };
 };
 
 
-THREE.TGALoader.prototype = {
-
-	constructor: THREE.TGALoader,
-
-	load: function ( url, onLoad, onProgress, onError ) {
-
-		var scope = this;
+// extend THREE.BinaryTextureLoader
+THREE.TGALoader.prototype = Object.create( THREE.BinaryTextureLoader.prototype );
+
+// reference from vthibault, https://github.com/vthibault/roBrowser/blob/master/src/Loaders/Targa.js
+THREE.TGALoader.prototype._parser = function ( buffer ) {
+
+	// TGA Constants
+	var TGA_TYPE_NO_DATA = 0,
+	TGA_TYPE_INDEXED = 1,
+	TGA_TYPE_RGB = 2,
+	TGA_TYPE_GREY = 3,
+	TGA_TYPE_RLE_INDEXED = 9,
+	TGA_TYPE_RLE_RGB = 10,
+	TGA_TYPE_RLE_GREY = 11,
+
+	TGA_ORIGIN_MASK = 0x30,
+	TGA_ORIGIN_SHIFT = 0x04,
+	TGA_ORIGIN_BL = 0x00,
+	TGA_ORIGIN_BR = 0x01,
+	TGA_ORIGIN_UL = 0x02,
+	TGA_ORIGIN_UR = 0x03;
+
+
+	if ( buffer.length < 19 )
+		console.error( 'THREE.TGALoader.parse: Not enough data to contain header.' );
+
+	var content = new Uint8Array( buffer ),
+		offset = 0,
+		header = {
+			id_length:       content[ offset ++ ],
+			colormap_type:   content[ offset ++ ],
+			image_type:      content[ offset ++ ],
+			colormap_index:  content[ offset ++ ] | content[ offset ++ ] << 8,
+			colormap_length: content[ offset ++ ] | content[ offset ++ ] << 8,
+			colormap_size:   content[ offset ++ ],
+
+			origin: [
+				content[ offset ++ ] | content[ offset ++ ] << 8,
+				content[ offset ++ ] | content[ offset ++ ] << 8
+			],
+			width:      content[ offset ++ ] | content[ offset ++ ] << 8,
+			height:     content[ offset ++ ] | content[ offset ++ ] << 8,
+			pixel_size: content[ offset ++ ],
+			flags:      content[ offset ++ ]
+		};
 
 
-		var texture = new THREE.DataTexture();
+	function tgaCheckHeader( header ) {
 
 
-		var loader = new THREE.XHRLoader( scope.manager );
-		loader.setResponseType( 'arraybuffer' );
-		loader.load( url, function ( buffer ) {
+		switch( header.image_type ) {
 
 
-			texture.image = scope.parse( buffer );
-			texture.needsUpdate = true;
+			// Check indexed type
+			case TGA_TYPE_INDEXED:
+			case TGA_TYPE_RLE_INDEXED:
+				if ( header.colormap_length > 256 || header.colormap_size !== 24 || header.colormap_type !== 1) {
+					console.error('THREE.TGALoader.parse.tgaCheckHeader: Invalid type colormap data for indexed type');
+				}
+				break;
 
 
-			if ( onLoad ) onLoad( texture );
+			// Check colormap type
+			case TGA_TYPE_RGB:
+			case TGA_TYPE_GREY:
+			case TGA_TYPE_RLE_RGB:
+			case TGA_TYPE_RLE_GREY:
+				if (header.colormap_type) {
+					console.error('THREE.TGALoader.parse.tgaCheckHeader: Invalid type colormap data for colormap type');
+				}
+				break;
 
 
-		}, onProgress, onError );
+			// What the need of a file without data ?
+			case TGA_TYPE_NO_DATA:
+				console.error('THREE.TGALoader.parse.tgaCheckHeader: No data');
 
 
-		return texture;
+			// Invalid type ?
+			default:
+				console.error('THREE.TGALoader.parse.tgaCheckHeader: Invalid type " '+ header.image_type + '"');
 
 
-	},
+		}
 
 
-	// reference from vthibault, https://github.com/vthibault/roBrowser/blob/master/src/Loaders/Targa.js
-	parse: function ( buffer ) {
+		// Check image width and height
+		if ( header.width <= 0 || header.height <=0 ) {
+			console.error( 'THREE.TGALoader.parse.tgaCheckHeader: Invalid image size' );
+		}
 
 
-		// TGA Constants
-		var TGA_TYPE_NO_DATA = 0,
-		TGA_TYPE_INDEXED = 1,
-		TGA_TYPE_RGB = 2,
-		TGA_TYPE_GREY = 3,
-		TGA_TYPE_RLE_INDEXED = 9,
-		TGA_TYPE_RLE_RGB = 10,
-		TGA_TYPE_RLE_GREY = 11,
+		// Check image pixel size
+		if (header.pixel_size !== 8  &&
+			header.pixel_size !== 16 &&
+			header.pixel_size !== 24 &&
+			header.pixel_size !== 32) {
+			console.error('THREE.TGALoader.parse.tgaCheckHeader: Invalid pixel size "' + header.pixel_size + '"');
+		}
 
 
-		TGA_ORIGIN_MASK = 0x30,
-		TGA_ORIGIN_SHIFT = 0x04,
-		TGA_ORIGIN_BL = 0x00,
-		TGA_ORIGIN_BR = 0x01,
-		TGA_ORIGIN_UL = 0x02,
-		TGA_ORIGIN_UR = 0x03;
+	}
 
 
+	// Check tga if it is valid format
+	tgaCheckHeader( header );
 
 
-		if ( buffer.length < 19 )
-			console.error( 'THREE.TGALoader.parse: Not enough data to contain header.' );
+	if ( header.id_length + offset > buffer.length ) {
+		console.error('THREE.TGALoader.parse: No data');
+	}
 
 
-		var content = new Uint8Array( buffer ),
-			offset = 0,
-			header = {
-				id_length:       content[ offset ++ ],
-				colormap_type:   content[ offset ++ ],
-				image_type:      content[ offset ++ ],
-				colormap_index:  content[ offset ++ ] | content[ offset ++ ] << 8,
-				colormap_length: content[ offset ++ ] | content[ offset ++ ] << 8,
-				colormap_size:   content[ offset ++ ],
+	// Skip the needn't data
+	offset += header.id_length;
 
 
-				origin: [
-					content[ offset ++ ] | content[ offset ++ ] << 8,
-					content[ offset ++ ] | content[ offset ++ ] << 8
-				],
-				width:      content[ offset ++ ] | content[ offset ++ ] << 8,
-				height:     content[ offset ++ ] | content[ offset ++ ] << 8,
-				pixel_size: content[ offset ++ ],
-				flags:      content[ offset ++ ]
-			};
+	// Get targa information about RLE compression and palette
+	var use_rle = false,
+		use_pal = false,
+		use_grey = false;
 
 
-		function tgaCheckHeader( header ) {
+	switch ( header.image_type ) {
 
 
-			switch( header.image_type ) {
+		case TGA_TYPE_RLE_INDEXED:
+			use_rle = true;
+			use_pal = true;
+			break;
 
 
-				// Check indexed type
-				case TGA_TYPE_INDEXED:
-				case TGA_TYPE_RLE_INDEXED:
-					if ( header.colormap_length > 256 || header.colormap_size !== 24 || header.colormap_type !== 1) {
-						console.error('THREE.TGALoader.parse.tgaCheckHeader: Invalid type colormap data for indexed type');
-					}
-					break;
+		case TGA_TYPE_INDEXED:
+			use_pal = true;
+			break;
 
 
-				// Check colormap type
-				case TGA_TYPE_RGB:
-				case TGA_TYPE_GREY:
-				case TGA_TYPE_RLE_RGB:
-				case TGA_TYPE_RLE_GREY:
-					if (header.colormap_type) {
-						console.error('THREE.TGALoader.parse.tgaCheckHeader: Invalid type colormap data for colormap type');
-					}
-					break;
+		case TGA_TYPE_RLE_RGB:
+			use_rle = true;
+			break;
 
 
-				// What the need of a file without data ?
-				case TGA_TYPE_NO_DATA:
-					console.error('THREE.TGALoader.parse.tgaCheckHeader: No data');
+		case TGA_TYPE_RGB:
+			break;
 
 
-				// Invalid type ?
-				default:
-					console.error('THREE.TGALoader.parse.tgaCheckHeader: Invalid type " '+ header.image_type + '"');
+		case TGA_TYPE_RLE_GREY:
+			use_rle = true;
+			use_grey = true;
+			break;
 
 
-			}
+		case TGA_TYPE_GREY:
+			use_grey = true;
+			break;
 
 
-			// Check image width and height
-			if ( header.width <= 0 || header.height <=0 ) {
-				console.error( 'THREE.TGALoader.parse.tgaCheckHeader: Invalid image size' );
-			}
-
-			// Check image pixel size
-			if (header.pixel_size !== 8  &&
-				header.pixel_size !== 16 &&
-				header.pixel_size !== 24 &&
-				header.pixel_size !== 32) {
-				console.error('THREE.TGALoader.parse.tgaCheckHeader: Invalid pixel size "' + header.pixel_size + '"');
-			}
-
-		}
-
-		// Check tga if it is valid format
-		tgaCheckHeader( header );
-
-		if ( header.id_length + offset > buffer.length ) {
-			console.error('THREE.TGALoader.parse: No data');
-		}
+	}
 
 
-		// Skip the needn't data
-		offset += header.id_length;
+	// Parse tga image buffer
+	function tgaParse( use_rle, use_pal, header, offset, data ) {
 
 
-		// Get targa information about RLE compression and palette
-		var use_rle = false,
-			use_pal = false,
-			use_grey = false;
+		var pixel_data,
+			pixel_size,
+			pixel_total,
+			palettes;
 
 
-		switch ( header.image_type ) {
+			pixel_size = header.pixel_size >> 3;
+			pixel_total = header.width * header.height * pixel_size;
 
 
-			case TGA_TYPE_RLE_INDEXED:
-				use_rle = true;
-				use_pal = true;
-				break;
+		 // Read palettes
+		 if ( use_pal ) {
+			 palettes = data.subarray( offset, offset += header.colormap_length * ( header.colormap_size >> 3 ) );
+		 }
 
 
-			case TGA_TYPE_INDEXED:
-				use_pal = true;
-				break;
+		 // Read RLE
+		 if ( use_rle ) {
+			 pixel_data = new Uint8Array(pixel_total);
 
 
-			case TGA_TYPE_RLE_RGB:
-				use_rle = true;
-				break;
+			var c, count, i;
+			var shift = 0;
+			var pixels = new Uint8Array(pixel_size);
 
 
-			case TGA_TYPE_RGB:
-				break;
+			while (shift < pixel_total) {
+				c     = data[offset++];
+				count = (c & 0x7f) + 1;
 
 
-			case TGA_TYPE_RLE_GREY:
-				use_rle = true;
-				use_grey = true;
-				break;
+				// RLE pixels.
+				if (c & 0x80) {
+					// Bind pixel tmp array
+					for (i = 0; i < pixel_size; ++i) {
+							pixels[i] = data[offset++];
+					}
 
 
-			case TGA_TYPE_GREY:
-				use_grey = true;
-				break;
+					// Copy pixel array
+					for (i = 0; i < count; ++i) {
+							pixel_data.set(pixels, shift + i * pixel_size);
+					}
 
 
-		}
+					shift += pixel_size * count;
 
 
-		// Parse tga image buffer
-		function tgaParse( use_rle, use_pal, header, offset, data ) {
-
-			var pixel_data,
-				pixel_size,
-				pixel_total,
-				palettes;
-
-				pixel_size = header.pixel_size >> 3;
-				pixel_total = header.width * header.height * pixel_size;
-
-			 // Read palettes
-			 if ( use_pal ) {
-				 palettes = data.subarray( offset, offset += header.colormap_length * ( header.colormap_size >> 3 ) );
-			 }
-
-			 // Read RLE
-			 if ( use_rle ) {
-				 pixel_data = new Uint8Array(pixel_total);
-
-				var c, count, i;
-				var shift = 0;
-				var pixels = new Uint8Array(pixel_size);
-
-				while (shift < pixel_total) {
-					c     = data[offset++];
-					count = (c & 0x7f) + 1;
-
-					// RLE pixels.
-					if (c & 0x80) {
-						// Bind pixel tmp array
-						for (i = 0; i < pixel_size; ++i) {
-								pixels[i] = data[offset++];
-						}
-
-						// Copy pixel array
-						for (i = 0; i < count; ++i) {
-								pixel_data.set(pixels, shift + i * pixel_size);
-						}
-
-						shift += pixel_size * count;
-
-					} else {
-						// Raw pixels.
-						count *= pixel_size;
-						for (i = 0; i < count; ++i) {
-								pixel_data[shift + i] = data[offset++];
-						}
-						shift += count;
+				} else {
+					// Raw pixels.
+					count *= pixel_size;
+					for (i = 0; i < count; ++i) {
+							pixel_data[shift + i] = data[offset++];
 					}
 					}
+					shift += count;
 				}
 				}
-			 } else {
-				// RAW Pixels
-				pixel_data = data.subarray(
-					 offset, offset += (use_pal ? header.width * header.height : pixel_total)
-				);
-			 }
-
-			 return {
-				pixel_data: pixel_data,
-				palettes: palettes
-			 };
-		}
+			}
+		 } else {
+			// RAW Pixels
+			pixel_data = data.subarray(
+				 offset, offset += (use_pal ? header.width * header.height : pixel_total)
+			);
+		 }
+
+		 return {
+			pixel_data: pixel_data,
+			palettes: palettes
+		 };
+	}
 
 
-		function tgaGetImageData8bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image, palettes) {
+	function tgaGetImageData8bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image, palettes) {
 
 
-			var colormap = palettes;
-			var color, i = 0, x, y;
-					var width = header.width;
+		var colormap = palettes;
+		var color, i = 0, x, y;
+				var width = header.width;
 
 
-			for (y = y_start; y !== y_end; y += y_step) {
-				for (x = x_start; x !== x_end; x += x_step, i++) {
-					color = image[i];
-					imageData[(x + width * y) * 4 + 3] = 255;
-					imageData[(x + width * y) * 4 + 2] = colormap[(color * 3) + 0];
-					imageData[(x + width * y) * 4 + 1] = colormap[(color * 3) + 1];
-					imageData[(x + width * y) * 4 + 0] = colormap[(color * 3) + 2];
-				}
+		for (y = y_start; y !== y_end; y += y_step) {
+			for (x = x_start; x !== x_end; x += x_step, i++) {
+				color = image[i];
+				imageData[(x + width * y) * 4 + 3] = 255;
+				imageData[(x + width * y) * 4 + 2] = colormap[(color * 3) + 0];
+				imageData[(x + width * y) * 4 + 1] = colormap[(color * 3) + 1];
+				imageData[(x + width * y) * 4 + 0] = colormap[(color * 3) + 2];
 			}
 			}
+		}
 
 
-			return imageData;
+		return imageData;
 
 
-		};
+	};
 
 
-		function tgaGetImageData16bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image) {
+	function tgaGetImageData16bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image) {
 
 
-			var color, i = 0, x, y;
-			var width = header.width;
+		var color, i = 0, x, y;
+		var width = header.width;
 
 
-			for (y = y_start; y !== y_end; y += y_step) {
-				for (x = x_start; x !== x_end; x += x_step, i += 2) {
-					color = image[i + 0] + (image[i + 1] << 8); // Inversed ?
-					imageData[(x + width * y) * 4 + 0] = (color & 0x7C00) >> 7;
-					imageData[(x + width * y) * 4 + 1] = (color & 0x03E0) >> 2;
-					imageData[(x + width * y) * 4 + 2] = (color & 0x001F) >> 3;
-					imageData[(x + width * y) * 4 + 3] = (color & 0x8000) ? 0 : 255;
-				}
+		for (y = y_start; y !== y_end; y += y_step) {
+			for (x = x_start; x !== x_end; x += x_step, i += 2) {
+				color = image[i + 0] + (image[i + 1] << 8); // Inversed ?
+				imageData[(x + width * y) * 4 + 0] = (color & 0x7C00) >> 7;
+				imageData[(x + width * y) * 4 + 1] = (color & 0x03E0) >> 2;
+				imageData[(x + width * y) * 4 + 2] = (color & 0x001F) >> 3;
+				imageData[(x + width * y) * 4 + 3] = (color & 0x8000) ? 0 : 255;
 			}
 			}
+		}
 
 
-			return imageData;
+		return imageData;
 
 
-		};
+	};
 
 
-		function tgaGetImageData24bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image) {
+	function tgaGetImageData24bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image) {
 
 
-			var i = 0, x, y;
-			var width = header.width;
+		var i = 0, x, y;
+		var width = header.width;
 
 
-			for (y = y_start; y !== y_end; y += y_step) {
-				for (x = x_start; x !== x_end; x += x_step, i += 3) {
-					imageData[(x + width * y) * 4 + 3] = 255;
-					imageData[(x + width * y) * 4 + 2] = image[i + 0];
-					imageData[(x + width * y) * 4 + 1] = image[i + 1];
-					imageData[(x + width * y) * 4 + 0] = image[i + 2];
-				}
+		for (y = y_start; y !== y_end; y += y_step) {
+			for (x = x_start; x !== x_end; x += x_step, i += 3) {
+				imageData[(x + width * y) * 4 + 3] = 255;
+				imageData[(x + width * y) * 4 + 2] = image[i + 0];
+				imageData[(x + width * y) * 4 + 1] = image[i + 1];
+				imageData[(x + width * y) * 4 + 0] = image[i + 2];
 			}
 			}
+		}
 
 
-			return imageData;
+		return imageData;
 
 
-		};
+	};
 
 
-		function tgaGetImageData32bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image) {
+	function tgaGetImageData32bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image) {
 
 
-			var i = 0, x, y;
-			var width = header.width;
+		var i = 0, x, y;
+		var width = header.width;
 
 
-			for (y = y_start; y !== y_end; y += y_step) {
-				for (x = x_start; x !== x_end; x += x_step, i += 4) {
-					imageData[(x + width * y) * 4 + 2] = image[i + 0];
-					imageData[(x + width * y) * 4 + 1] = image[i + 1];
-					imageData[(x + width * y) * 4 + 0] = image[i + 2];
-					imageData[(x + width * y) * 4 + 3] = image[i + 3];
-				}
+		for (y = y_start; y !== y_end; y += y_step) {
+			for (x = x_start; x !== x_end; x += x_step, i += 4) {
+				imageData[(x + width * y) * 4 + 2] = image[i + 0];
+				imageData[(x + width * y) * 4 + 1] = image[i + 1];
+				imageData[(x + width * y) * 4 + 0] = image[i + 2];
+				imageData[(x + width * y) * 4 + 3] = image[i + 3];
 			}
 			}
+		}
 
 
-			return imageData;
+		return imageData;
 
 
-		};
+	};
 
 
-		function tgaGetImageDataGrey8bits( imageData, y_start, y_step, y_end, x_start, x_step, x_end, image ) {
+	function tgaGetImageDataGrey8bits( imageData, y_start, y_step, y_end, x_start, x_step, x_end, image ) {
 
 
-			var color, i = 0, x, y;
-			var width = header.width;
+		var color, i = 0, x, y;
+		var width = header.width;
 
 
-			for (y = y_start; y !== y_end; y += y_step) {
-				for (x = x_start; x !== x_end; x += x_step, i++) {
-					color = image[i];
-					imageData[(x + width * y) * 4 + 0] = color;
-					imageData[(x + width * y) * 4 + 1] = color;
-					imageData[(x + width * y) * 4 + 2] = color;
-					imageData[(x + width * y) * 4 + 3] = 255;
-				}
+		for (y = y_start; y !== y_end; y += y_step) {
+			for (x = x_start; x !== x_end; x += x_step, i++) {
+				color = image[i];
+				imageData[(x + width * y) * 4 + 0] = color;
+				imageData[(x + width * y) * 4 + 1] = color;
+				imageData[(x + width * y) * 4 + 2] = color;
+				imageData[(x + width * y) * 4 + 3] = 255;
 			}
 			}
+		}
 
 
-			return imageData;
+		return imageData;
 
 
-		};
+	};
 
 
-		function tgaGetImageDataGrey16bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image) {
+	function tgaGetImageDataGrey16bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image) {
 
 
-			var i = 0, x, y;
-			var width = header.width;
+		var i = 0, x, y;
+		var width = header.width;
 
 
-			for (y = y_start; y !== y_end; y += y_step) {
-				for (x = x_start; x !== x_end; x += x_step, i += 2) {
-					imageData[(x + width * y) * 4 + 0] = image[i + 0];
-					imageData[(x + width * y) * 4 + 1] = image[i + 0];
-					imageData[(x + width * y) * 4 + 2] = image[i + 0];
-					imageData[(x + width * y) * 4 + 3] = image[i + 1];
-				}
+		for (y = y_start; y !== y_end; y += y_step) {
+			for (x = x_start; x !== x_end; x += x_step, i += 2) {
+				imageData[(x + width * y) * 4 + 0] = image[i + 0];
+				imageData[(x + width * y) * 4 + 1] = image[i + 0];
+				imageData[(x + width * y) * 4 + 2] = image[i + 0];
+				imageData[(x + width * y) * 4 + 3] = image[i + 1];
 			}
 			}
+		}
+
+		return imageData;
+
+	};
+
+	function getTgaRGBA( width, height, image, palette ) {
+
+		var x_start,
+			y_start,
+			x_step,
+			y_step,
+			x_end,
+			y_end,
+			data = new Uint8Array(width * height * 4);
+
+		switch( (header.flags & TGA_ORIGIN_MASK) >> TGA_ORIGIN_SHIFT ) {
+			default:
+			case TGA_ORIGIN_UL:
+				x_start = 0;
+				x_step = 1;
+				x_end = width;
+				y_start = 0;
+				y_step = 1;
+				y_end = height;
+				break;
 
 
-			return imageData;
+			case TGA_ORIGIN_BL:
+				x_start = 0;
+				x_step = 1;
+				x_end = width;
+				y_start = height - 1;
+				y_step = -1;
+				y_end = -1;
+				break;
 
 
-		};
+			case TGA_ORIGIN_UR:
+				x_start = width - 1;
+				x_step = -1;
+				x_end = -1;
+				y_start = 0;
+				y_step = 1;
+				y_end = height;
+				break;
 
 
-		function getTgaRGBA( width, height, image, palette ) {
+			case TGA_ORIGIN_BR:
+				x_start = width - 1;
+				x_step = -1;
+				x_end = -1;
+				y_start = height - 1;
+				y_step = -1;
+				y_end = -1;
+				break;
 
 
-			var x_start,
-				y_start,
-				x_step,
-				y_step,
-				x_end,
-				y_end,
-				data = new Uint8Array(width * height * 4);
+		}
 
 
-			switch( (header.flags & TGA_ORIGIN_MASK) >> TGA_ORIGIN_SHIFT ) {
-				default:
-				case TGA_ORIGIN_UL:
-					x_start = 0;
-					x_step = 1;
-					x_end = width;
-					y_start = 0;
-					y_step = 1;
-					y_end = height;
-					break;
+		if ( use_grey ) {
 
 
-				case TGA_ORIGIN_BL:
-					x_start = 0;
-					x_step = 1;
-					x_end = width;
-					y_start = height - 1;
-					y_step = -1;
-					y_end = -1;
+			switch( header.pixel_size ) {
+				case 8:
+					tgaGetImageDataGrey8bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
 					break;
 					break;
-
-				case TGA_ORIGIN_UR:
-					x_start = width - 1;
-					x_step = -1;
-					x_end = -1;
-					y_start = 0;
-					y_step = 1;
-					y_end = height;
+				case 16:
+					tgaGetImageDataGrey16bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
 					break;
 					break;
-
-				case TGA_ORIGIN_BR:
-					x_start = width - 1;
-					x_step = -1;
-					x_end = -1;
-					y_start = height - 1;
-					y_step = -1;
-					y_end = -1;
+				default:
+					console.error( 'THREE.TGALoader.parse.getTgaRGBA: not support this format' );
 					break;
 					break;
-
 			}
 			}
 
 
-			if ( use_grey ) {
-
-				switch( header.pixel_size ) {
-					case 8:
-						tgaGetImageDataGrey8bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
-						break;
-					case 16:
-						tgaGetImageDataGrey16bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
-						break;
-					default:
-						console.error( 'THREE.TGALoader.parse.getTgaRGBA: not support this format' );
-						break;
-				}
-
-			} else {
-
-				switch( header.pixel_size ) {
-					case 8:
-						tgaGetImageData8bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image, palette );
-						break;
+		} else {
 
 
-					case 16:
-						tgaGetImageData16bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
-						break;
+			switch( header.pixel_size ) {
+				case 8:
+					tgaGetImageData8bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image, palette );
+					break;
 
 
-					case 24:
-						tgaGetImageData24bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
-						break;
+				case 16:
+					tgaGetImageData16bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
+					break;
 
 
-					case 32:
-						tgaGetImageData32bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
-						break;
+				case 24:
+					tgaGetImageData24bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
+					break;
 
 
-					default:
-						console.error( 'THREE.TGALoader.parse.getTgaRGBA: not support this format' );
-						break;
-				}
+				case 32:
+					tgaGetImageData32bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
+					break;
 
 
+				default:
+					console.error( 'THREE.TGALoader.parse.getTgaRGBA: not support this format' );
+					break;
 			}
 			}
 
 
-			// Load image data according to specific method
-			// var func = 'tgaGetImageData' + (use_grey ? 'Grey' : '') + (header.pixel_size) + 'bits';
-			// func(data, y_start, y_step, y_end, x_start, x_step, x_end, width, image, palette );
-			return data;
-
 		}
 		}
 
 
-		var result = tgaParse( use_rle, use_pal, header, offset, content );
-		var rgbaData = getTgaRGBA( header.width, header.height, result.pixel_data, result.palettes );
-
-		return {
-			width: header.width,
-			height: header.height,
-			data: rgbaData
-		};
+		// Load image data according to specific method
+		// var func = 'tgaGetImageData' + (use_grey ? 'Grey' : '') + (header.pixel_size) + 'bits';
+		// func(data, y_start, y_step, y_end, x_start, x_step, x_end, width, image, palette );
+		return data;
 
 
 	}
 	}
 
 
+	var result = tgaParse( use_rle, use_pal, header, offset, content );
+	var rgbaData = getTgaRGBA( header.width, header.height, result.pixel_data, result.palettes );
+
+	return {
+		width: header.width,
+		height: header.height,
+		data: rgbaData
+	};
+
 };
 };

File diff suppressed because it is too large
+ 10 - 0
examples/textures/miranda_uncropped.hdr


+ 234 - 0
examples/webgl_materials_texture_hdr.html

@@ -0,0 +1,234 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - materials - HDR texture loader</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				color: #fff;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+				font-weight: bold;
+
+				background-color: #000;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			#info {
+				color:#fff;
+				position: absolute;
+				top: 0px; width: 100%;
+				padding: 5px;
+
+			}
+
+			a { color: red; }
+
+		</style>
+	</head>
+	<body>
+
+		<div id="container"></div>
+		<div id="info">
+			<a href="http://threejs.org" target="_blank">three.js</a> - webgl HDR texture loader example -
+			based on <a href="http://spidergl.org/example.php?id=13" target="_blank">SpiderGL</a>
+		</div>
+
+		<script src="../build/three.min.js"></script>
+		<script src="js/loaders/RGBELoader.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/libs/stats.min.js"></script>
+
+		<!-- HDR fragment shader -->
+
+		<script id="fs-hdr" type="x-shader/x-fragment">
+
+			uniform sampler2D   tDiffuse;
+			uniform float       exposure;
+			uniform float       brightMax;
+
+			varying vec2  vUv;
+
+			vec3 decode_pnghdr( const in vec4 color ) {
+
+				vec4 rgbcolor = vec4( 0.0, 0.0, 0.0, 0.0 );
+
+				if ( color.w > 0.0 ) {
+					float f = pow(2.0, 127.0*(color.w-0.5));
+					rgbcolor.xyz = color.xyz * f;
+				}
+				return rgbcolor.xyz;
+
+				/*
+				// remove gamma correction
+				vec4 res = color * color;
+
+				// decoded RI
+				float ri = pow( 2.0, res.w * 32.0 - 16.0 );
+
+				// decoded HDR pixel
+				res.xyz = res.xyz * ri;
+				return res.xyz;
+				*/
+			}
+
+			void main()	{
+
+				vec4 color = texture2D( tDiffuse, vUv );
+				color.xyz  = decode_pnghdr( color );
+
+				// apply gamma correction and exposure
+				//gl_FragColor = vec4( pow( exposure * color.xyz, vec3( 0.474 ) ), 1.0 );
+
+				// Perform tone-mapping
+				float Y = dot(vec4(0.30, 0.59, 0.11, 0.0), color);
+				float YD = exposure * (exposure/brightMax + 1.0) / (exposure + 1.0);
+				color *= YD;
+
+				gl_FragColor = vec4( color.xyz, 1.0 );
+
+			}
+
+		</script>
+
+		<!-- HDR vertex shader -->
+
+		<script id="vs-hdr" type="x-shader/x-vertex">
+
+			varying vec2 vUv;
+
+			void main()	{
+
+				vUv  = uv;
+				gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+			}
+
+		</script>
+
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var container, stats;
+
+			var camera, scene, renderer;
+			var materialHDR, quad, gamma, exposure;
+
+			var sign = 1, rate = 1;
+
+			var clock = new THREE.Clock();
+
+			init();
+
+			function init() {
+
+				container = document.getElementById( 'container' );
+
+				camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 10000 );
+				camera.position.z = 900;
+
+				scene = new THREE.Scene();
+
+				var loader = new THREE.RGBELoader();
+
+				var texture = loader.load( "textures/miranda_uncropped.hdr", function( texture, textureData ){
+					console.log( textureData.header ); // header string
+					console.log( [textureData.width, textureData.height] ); // dimensions
+					materialHDR = new THREE.ShaderMaterial( {
+
+						uniforms: {
+							tDiffuse:  { type: "t", value: texture },
+							exposure:  { type: "f", value: textureData.exposure },
+							brightMax: { type: "f", value: textureData.gamma }
+							},
+						vertexShader: getText( 'vs-hdr' ),
+						fragmentShader: getText( 'fs-hdr' )
+
+					} );
+					quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( textureData.width, textureData.height ), materialHDR );
+					quad.position.z = -100;
+					scene.add( quad );
+					animate();
+				} );
+				texture.minFilter = THREE.LinearFilter;
+				texture.magFilter = THREE.NearestFilter;
+
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				container.appendChild( renderer.domElement );
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				container.appendChild( stats.domElement );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			function getText( id ) {
+
+				return document.getElementById( id ).textContent;
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+
+			function render() {
+
+				delta = clock.getDelta() * 5;
+
+				if ( materialHDR.uniforms.exposure.value > 0 || materialHDR.uniforms.exposure.value < 1 ) {
+
+					rate = 0.25;
+
+				} else {
+
+					rate = 1;
+
+				}
+
+				if ( materialHDR.uniforms.exposure.value > 5 || materialHDR.uniforms.exposure.value <= 0 ) {
+
+					sign *= -1;
+
+				}
+
+				materialHDR.uniforms.exposure.value += sign * rate * delta;
+
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+	</body>
+</html>

+ 2 - 0
src/Three.js

@@ -162,6 +162,8 @@ THREE.RGBFormat = 1020;
 THREE.RGBAFormat = 1021;
 THREE.RGBAFormat = 1021;
 THREE.LuminanceFormat = 1022;
 THREE.LuminanceFormat = 1022;
 THREE.LuminanceAlphaFormat = 1023;
 THREE.LuminanceAlphaFormat = 1023;
+// THREE.RGBEFormat handled as THREE.RGBAFormat in shaders
+THREE.RGBEFormat = THREE.RGBAFormat; //1024;
 
 
 // DDS / ST3C Compressed texture formats
 // DDS / ST3C Compressed texture formats
 
 

+ 87 - 0
src/loaders/BinaryTextureLoader.js

@@ -0,0 +1,87 @@
+/**
+ * @author Nikos M. / https://github.com/foo123/
+ *
+ * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)
+ */
+
+THREE.DataTextureLoader = THREE.BinaryTextureLoader = function () {
+
+	// override in sub classes
+	this._parser = null;
+
+};
+
+THREE.BinaryTextureLoader.prototype = {
+
+	constructor: THREE.BinaryTextureLoader,
+
+	load: function ( url, onLoad, onProgress, onError ) {
+
+		var scope = this;
+
+		var texture = new THREE.DataTexture( );
+
+		var loader = new THREE.XHRLoader();
+		loader.setResponseType( 'arraybuffer' );
+
+		loader.load( url, function ( buffer ) {
+
+			var texData = scope._parser( buffer );
+
+			if ( !texData ) return;
+
+			if ( undefined !== texData.image ) {
+
+				texture.image = texData.image;
+
+			} else if ( undefined !== texData.data ){
+
+				texture.image.width = texData.width;
+				texture.image.height = texData.height;
+				texture.image.data = texData.data;
+
+			}
+
+			texture.wrapS = undefined !== texData.wrapS ? texData.wrapS : THREE.ClampToEdgeWrapping;
+			texture.wrapT = undefined !== texData.wrapT ? texData.wrapT : THREE.ClampToEdgeWrapping;
+
+			texture.magFilter = undefined !== texData.magFilter ? texData.magFilter : THREE.LinearFilter;
+			texture.minFilter = undefined !== texData.minFilter ? texData.minFilter : THREE.LinearMipMapLinearFilter;
+
+			texture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;
+
+			if ( undefined !== texData.format ) {
+
+				texture.format = texData.format;
+
+			}
+			if ( undefined !== texData.type ) {
+
+				texture.type = texData.type;
+
+			}
+
+			if ( undefined !== texData.mipmaps ) {
+
+				texture.mipmaps = texData.mipmaps;
+
+			}
+
+			if ( 1 === texData.mipmapCount ) {
+
+				texture.minFilter = THREE.LinearFilter;
+
+			}
+
+			texture.needsUpdate = true;
+
+			if ( onLoad ) onLoad( texture, texData );
+
+		}, onProgress, onError );
+
+
+		return texture;
+
+	}
+
+};

+ 1 - 0
utils/build/includes/common.json

@@ -48,6 +48,7 @@
 	"src/loaders/MaterialLoader.js",
 	"src/loaders/MaterialLoader.js",
 	"src/loaders/ObjectLoader.js",
 	"src/loaders/ObjectLoader.js",
 	"src/loaders/TextureLoader.js",
 	"src/loaders/TextureLoader.js",
+	"src/loaders/BinaryTextureLoader.js",
 	"src/loaders/CompressedTextureLoader.js",
 	"src/loaders/CompressedTextureLoader.js",
 	"src/materials/Material.js",
 	"src/materials/Material.js",
 	"src/materials/LineBasicMaterial.js",
 	"src/materials/LineBasicMaterial.js",

Some files were not shown because too many files changed in this diff