TextureHelperGPU.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import {
  2. BoxGeometry,
  3. BufferAttribute,
  4. Mesh,
  5. PlaneGeometry,
  6. Vector3,
  7. } from 'three';
  8. import { NodeMaterial, texture as textureNode, cubeTexture, texture3D, float, vec4 } from 'three/tsl';
  9. import { mergeGeometries } from '../utils/BufferGeometryUtils.js';
  10. class TextureHelper extends Mesh {
  11. constructor( texture, width = 1, height = 1, depth = 1 ) {
  12. const material = new NodeMaterial();
  13. material.name = 'TextureHelper';
  14. let colorNode;
  15. if ( texture.isCubeTexture ) {
  16. colorNode = cubeTexture( texture );
  17. } else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
  18. colorNode = texture3D( texture );
  19. } else {
  20. colorNode = textureNode( texture );
  21. }
  22. const alphaNode = float( getAlpha( texture ) );
  23. material.colorNode = vec4( colorNode.rgb, alphaNode );
  24. const geometry = texture.isCubeTexture
  25. ? createCubeGeometry( width, height, depth )
  26. : createSliceGeometry( texture, width, height, depth );
  27. super( geometry, material );
  28. this.texture = texture;
  29. this.type = 'TextureHelper';
  30. }
  31. dispose() {
  32. this.geometry.dispose();
  33. this.material.dispose();
  34. }
  35. }
  36. function getImageCount( texture ) {
  37. if ( texture.isCubeTexture ) {
  38. return 6;
  39. } else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
  40. return texture.image.depth;
  41. } else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
  42. return texture.image.depth;
  43. } else {
  44. return 1;
  45. }
  46. }
  47. function getAlpha( texture ) {
  48. if ( texture.isCubeTexture ) {
  49. return 1;
  50. } else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
  51. return Math.max( 1 / texture.image.depth, 0.25 );
  52. } else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
  53. return Math.max( 1 / texture.image.depth, 0.25 );
  54. } else {
  55. return 1;
  56. }
  57. }
  58. function createCubeGeometry( width, height, depth ) {
  59. const geometry = new BoxGeometry( width, height, depth );
  60. const position = geometry.attributes.position;
  61. const uv = geometry.attributes.uv;
  62. const uvw = new BufferAttribute( new Float32Array( uv.count * 3 ), 3 );
  63. const _direction = new Vector3();
  64. for ( let j = 0, jl = uv.count; j < jl; ++ j ) {
  65. _direction.fromBufferAttribute( position, j ).normalize();
  66. const u = _direction.x;
  67. const v = _direction.y;
  68. const w = _direction.z;
  69. uvw.setXYZ( j, u, v, w );
  70. }
  71. geometry.deleteAttribute( 'uv' );
  72. geometry.setAttribute( 'uv', uvw );
  73. return geometry;
  74. }
  75. function createSliceGeometry( texture, width, height, depth ) {
  76. const sliceCount = getImageCount( texture );
  77. const geometries = [];
  78. for ( let i = 0; i < sliceCount; ++ i ) {
  79. const geometry = new PlaneGeometry( width, height );
  80. if ( sliceCount > 1 ) {
  81. geometry.translate( 0, 0, depth * ( i / ( sliceCount - 1 ) - 0.5 ) );
  82. }
  83. const uv = geometry.attributes.uv;
  84. const uvw = new BufferAttribute( new Float32Array( uv.count * 3 ), 3 );
  85. for ( let j = 0, jl = uv.count; j < jl; ++ j ) {
  86. const u = uv.getX( j );
  87. const v = texture.flipY ? uv.getY( j ) : 1 - uv.getY( j );
  88. const w = sliceCount === 1
  89. ? 1
  90. : texture.isDataArrayTexture || texture.isCompressedArrayTexture
  91. ? i
  92. : i / ( sliceCount - 1 );
  93. uvw.setXYZ( j, u, v, w );
  94. }
  95. geometry.deleteAttribute( 'uv' );
  96. geometry.setAttribute( 'uv', uvw );
  97. geometries.push( geometry );
  98. }
  99. return mergeGeometries( geometries );
  100. }
  101. export { TextureHelper };
粤ICP备19079148号