Texture.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. * @author alteredq / http://alteredqualia.com/
  4. * @author szimek / https://github.com/szimek/
  5. */
  6. THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
  7. Object.defineProperty( this, 'id', { value: THREE.TextureIdCount ++ } );
  8. this.uuid = THREE.Math.generateUUID();
  9. this.name = '';
  10. this.sourceFile = '';
  11. this.image = image !== undefined ? image : THREE.Texture.DEFAULT_IMAGE;
  12. this.mipmaps = [];
  13. this.mapping = mapping !== undefined ? mapping : THREE.Texture.DEFAULT_MAPPING;
  14. this.wrapS = wrapS !== undefined ? wrapS : THREE.ClampToEdgeWrapping;
  15. this.wrapT = wrapT !== undefined ? wrapT : THREE.ClampToEdgeWrapping;
  16. this.magFilter = magFilter !== undefined ? magFilter : THREE.LinearFilter;
  17. this.minFilter = minFilter !== undefined ? minFilter : THREE.LinearMipMapLinearFilter;
  18. this.anisotropy = anisotropy !== undefined ? anisotropy : 1;
  19. this.format = format !== undefined ? format : THREE.RGBAFormat;
  20. this.type = type !== undefined ? type : THREE.UnsignedByteType;
  21. this.offset = new THREE.Vector2( 0, 0 );
  22. this.repeat = new THREE.Vector2( 1, 1 );
  23. this.generateMipmaps = true;
  24. this.premultiplyAlpha = false;
  25. this.flipY = true;
  26. this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
  27. // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.
  28. //
  29. // Also changing the encoding after already used by a Material will not automatically make the Material
  30. // update. You need to explicitly call Material.needsUpdate to trigger it to recompile.
  31. this.encoding = THREE.LinearEncoding;
  32. this.version = 0;
  33. this.onUpdate = null;
  34. };
  35. THREE.Texture.DEFAULT_IMAGE = undefined;
  36. THREE.Texture.DEFAULT_MAPPING = THREE.UVMapping;
  37. THREE.Texture.prototype = {
  38. constructor: THREE.Texture,
  39. set needsUpdate ( value ) {
  40. if ( value === true ) this.version ++;
  41. },
  42. clone: function () {
  43. return new this.constructor().copy( this );
  44. },
  45. copy: function ( source ) {
  46. this.image = source.image;
  47. this.mipmaps = source.mipmaps.slice( 0 );
  48. this.mapping = source.mapping;
  49. this.wrapS = source.wrapS;
  50. this.wrapT = source.wrapT;
  51. this.magFilter = source.magFilter;
  52. this.minFilter = source.minFilter;
  53. this.anisotropy = source.anisotropy;
  54. this.format = source.format;
  55. this.type = source.type;
  56. this.offset.copy( source.offset );
  57. this.repeat.copy( source.repeat );
  58. this.generateMipmaps = source.generateMipmaps;
  59. this.premultiplyAlpha = source.premultiplyAlpha;
  60. this.flipY = source.flipY;
  61. this.unpackAlignment = source.unpackAlignment;
  62. this.encoding = source.encoding;
  63. return this;
  64. },
  65. toJSON: function ( meta ) {
  66. if ( meta.textures[ this.uuid ] !== undefined ) {
  67. return meta.textures[ this.uuid ];
  68. }
  69. function getDataURL( image ) {
  70. var canvas;
  71. if ( image.toDataURL !== undefined ) {
  72. canvas = image;
  73. } else {
  74. canvas = document.createElement( 'canvas' );
  75. canvas.width = image.width;
  76. canvas.height = image.height;
  77. canvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );
  78. }
  79. if ( canvas.width > 2048 || canvas.height > 2048 ) {
  80. return canvas.toDataURL( 'image/jpeg', 0.6 );
  81. } else {
  82. return canvas.toDataURL( 'image/png' );
  83. }
  84. }
  85. var output = {
  86. metadata: {
  87. version: 4.4,
  88. type: 'Texture',
  89. generator: 'Texture.toJSON'
  90. },
  91. uuid: this.uuid,
  92. name: this.name,
  93. mapping: this.mapping,
  94. repeat: [ this.repeat.x, this.repeat.y ],
  95. offset: [ this.offset.x, this.offset.y ],
  96. wrap: [ this.wrapS, this.wrapT ],
  97. minFilter: this.minFilter,
  98. magFilter: this.magFilter,
  99. anisotropy: this.anisotropy
  100. };
  101. if ( this.image !== undefined ) {
  102. // TODO: Move to THREE.Image
  103. var image = this.image;
  104. if ( image.uuid === undefined ) {
  105. image.uuid = THREE.Math.generateUUID(); // UGH
  106. }
  107. if ( meta.images[ image.uuid ] === undefined ) {
  108. meta.images[ image.uuid ] = {
  109. uuid: image.uuid,
  110. url: getDataURL( image )
  111. };
  112. }
  113. output.image = image.uuid;
  114. }
  115. meta.textures[ this.uuid ] = output;
  116. return output;
  117. },
  118. dispose: function () {
  119. this.dispatchEvent( { type: 'dispose' } );
  120. },
  121. transformUv: function ( uv ) {
  122. if ( this.mapping !== THREE.UVMapping ) return;
  123. uv.multiply( this.repeat );
  124. uv.add( this.offset );
  125. if ( uv.x < 0 || uv.x > 1 ) {
  126. switch ( this.wrapS ) {
  127. case THREE.RepeatWrapping:
  128. uv.x = uv.x - Math.floor( uv.x );
  129. break;
  130. case THREE.ClampToEdgeWrapping:
  131. uv.x = uv.x < 0 ? 0 : 1;
  132. break;
  133. case THREE.MirroredRepeatWrapping:
  134. if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {
  135. uv.x = Math.ceil( uv.x ) - uv.x;
  136. } else {
  137. uv.x = uv.x - Math.floor( uv.x );
  138. }
  139. break;
  140. }
  141. }
  142. if ( uv.y < 0 || uv.y > 1 ) {
  143. switch ( this.wrapT ) {
  144. case THREE.RepeatWrapping:
  145. uv.y = uv.y - Math.floor( uv.y );
  146. break;
  147. case THREE.ClampToEdgeWrapping:
  148. uv.y = uv.y < 0 ? 0 : 1;
  149. break;
  150. case THREE.MirroredRepeatWrapping:
  151. if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {
  152. uv.y = Math.ceil( uv.y ) - uv.y;
  153. } else {
  154. uv.y = uv.y - Math.floor( uv.y );
  155. }
  156. break;
  157. }
  158. }
  159. if ( this.flipY ) {
  160. uv.y = 1 - uv.y;
  161. }
  162. }
  163. };
  164. THREE.EventDispatcher.prototype.apply( THREE.Texture.prototype );
  165. THREE.TextureIdCount = 0;
粤ICP备19079148号