ImageUtils.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /**
  2. * @author alteredq / http://alteredqualia.com/
  3. * @author mrdoob / http://mrdoob.com/
  4. * @author Daosheng Mu / https://github.com/DaoshengMu/
  5. */
  6. THREE.ImageUtils = {
  7. crossOrigin: undefined,
  8. loadTexture: function ( url, mapping, onLoad, onError ) {
  9. var loader = new THREE.ImageLoader();
  10. loader.crossOrigin = this.crossOrigin;
  11. var texture = new THREE.Texture();
  12. texture.mapping = mapping;
  13. loader.load( url, function ( image ) {
  14. texture.image = image;
  15. texture.needsUpdate = true;
  16. if ( onLoad ) onLoad( texture );
  17. }, undefined, function ( event ) {
  18. if ( onError ) onError( event );
  19. } );
  20. texture.sourceFile = url;
  21. return texture;
  22. },
  23. loadTextureCube: function ( array, mapping, onLoad, onError ) {
  24. var images = [];
  25. var loader = new THREE.ImageLoader();
  26. loader.crossOrigin = this.crossOrigin;
  27. var texture = new THREE.CubeTexture( images, mapping );
  28. // no flipping needed for cube textures
  29. texture.flipY = false;
  30. var loaded = 0;
  31. var loadTexture = function ( i ) {
  32. loader.load( array[ i ], function ( image ) {
  33. texture.images[ i ] = image;
  34. loaded += 1;
  35. if ( loaded === 6 ) {
  36. texture.needsUpdate = true;
  37. if ( onLoad ) onLoad( texture );
  38. }
  39. } );
  40. }
  41. for ( var i = 0, il = array.length; i < il; ++ i ) {
  42. loadTexture( i );
  43. }
  44. return texture;
  45. },
  46. loadCompressedTexture: function () {
  47. console.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' )
  48. },
  49. loadCompressedTextureCube: function () {
  50. console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' )
  51. },
  52. getNormalMap: function ( image, depth ) {
  53. // Adapted from http://www.paulbrunt.co.uk/lab/heightnormal/
  54. var cross = function ( a, b ) {
  55. return [ a[ 1 ] * b[ 2 ] - a[ 2 ] * b[ 1 ], a[ 2 ] * b[ 0 ] - a[ 0 ] * b[ 2 ], a[ 0 ] * b[ 1 ] - a[ 1 ] * b[ 0 ] ];
  56. }
  57. var subtract = function ( a, b ) {
  58. return [ a[ 0 ] - b[ 0 ], a[ 1 ] - b[ 1 ], a[ 2 ] - b[ 2 ] ];
  59. }
  60. var normalize = function ( a ) {
  61. var l = Math.sqrt( a[ 0 ] * a[ 0 ] + a[ 1 ] * a[ 1 ] + a[ 2 ] * a[ 2 ] );
  62. return [ a[ 0 ] / l, a[ 1 ] / l, a[ 2 ] / l ];
  63. }
  64. depth = depth | 1;
  65. var width = image.width;
  66. var height = image.height;
  67. var canvas = document.createElement( 'canvas' );
  68. canvas.width = width;
  69. canvas.height = height;
  70. var context = canvas.getContext( '2d' );
  71. context.drawImage( image, 0, 0 );
  72. var data = context.getImageData( 0, 0, width, height ).data;
  73. var imageData = context.createImageData( width, height );
  74. var output = imageData.data;
  75. for ( var x = 0; x < width; x ++ ) {
  76. for ( var y = 0; y < height; y ++ ) {
  77. var ly = y - 1 < 0 ? 0 : y - 1;
  78. var uy = y + 1 > height - 1 ? height - 1 : y + 1;
  79. var lx = x - 1 < 0 ? 0 : x - 1;
  80. var ux = x + 1 > width - 1 ? width - 1 : x + 1;
  81. var points = [];
  82. var origin = [ 0, 0, data[ ( y * width + x ) * 4 ] / 255 * depth ];
  83. points.push( [ - 1, 0, data[ ( y * width + lx ) * 4 ] / 255 * depth ] );
  84. points.push( [ - 1, - 1, data[ ( ly * width + lx ) * 4 ] / 255 * depth ] );
  85. points.push( [ 0, - 1, data[ ( ly * width + x ) * 4 ] / 255 * depth ] );
  86. points.push( [ 1, - 1, data[ ( ly * width + ux ) * 4 ] / 255 * depth ] );
  87. points.push( [ 1, 0, data[ ( y * width + ux ) * 4 ] / 255 * depth ] );
  88. points.push( [ 1, 1, data[ ( uy * width + ux ) * 4 ] / 255 * depth ] );
  89. points.push( [ 0, 1, data[ ( uy * width + x ) * 4 ] / 255 * depth ] );
  90. points.push( [ - 1, 1, data[ ( uy * width + lx ) * 4 ] / 255 * depth ] );
  91. var normals = [];
  92. var num_points = points.length;
  93. for ( var i = 0; i < num_points; i ++ ) {
  94. var v1 = points[ i ];
  95. var v2 = points[ ( i + 1 ) % num_points ];
  96. v1 = subtract( v1, origin );
  97. v2 = subtract( v2, origin );
  98. normals.push( normalize( cross( v1, v2 ) ) );
  99. }
  100. var normal = [ 0, 0, 0 ];
  101. for ( var i = 0; i < normals.length; i ++ ) {
  102. normal[ 0 ] += normals[ i ][ 0 ];
  103. normal[ 1 ] += normals[ i ][ 1 ];
  104. normal[ 2 ] += normals[ i ][ 2 ];
  105. }
  106. normal[ 0 ] /= normals.length;
  107. normal[ 1 ] /= normals.length;
  108. normal[ 2 ] /= normals.length;
  109. var idx = ( y * width + x ) * 4;
  110. output[ idx ] = ( ( normal[ 0 ] + 1.0 ) / 2.0 * 255 ) | 0;
  111. output[ idx + 1 ] = ( ( normal[ 1 ] + 1.0 ) / 2.0 * 255 ) | 0;
  112. output[ idx + 2 ] = ( normal[ 2 ] * 255 ) | 0;
  113. output[ idx + 3 ] = 255;
  114. }
  115. }
  116. context.putImageData( imageData, 0, 0 );
  117. return canvas;
  118. },
  119. generateDataTexture: function ( width, height, color ) {
  120. var size = width * height;
  121. var data = new Uint8Array( 3 * size );
  122. var r = Math.floor( color.r * 255 );
  123. var g = Math.floor( color.g * 255 );
  124. var b = Math.floor( color.b * 255 );
  125. for ( var i = 0; i < size; i ++ ) {
  126. data[ i * 3 ] = r;
  127. data[ i * 3 + 1 ] = g;
  128. data[ i * 3 + 2 ] = b;
  129. }
  130. var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat );
  131. texture.needsUpdate = true;
  132. return texture;
  133. }
  134. };