WebGLTextureUtils.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import {
  2. PlaneGeometry,
  3. ShaderMaterial,
  4. Uniform,
  5. Mesh,
  6. PerspectiveCamera,
  7. Scene,
  8. WebGLRenderer,
  9. CanvasTexture,
  10. SRGBColorSpace
  11. } from 'three';
  12. /**
  13. * @module WebGLTextureUtils
  14. * @three_import import * as WebGLTextureUtils from 'three/addons/utils/WebGLTextureUtils.js';
  15. */
  16. let _renderer;
  17. let fullscreenQuadGeometry;
  18. let fullscreenQuadMaterial;
  19. let fullscreenQuad;
  20. /**
  21. * Returns an uncompressed version of the given compressed texture.
  22. *
  23. * This module can only be used with {@link WebGLRenderer}. When using {@link WebGPURenderer},
  24. * import the function from {@link WebGPUTextureUtils}.
  25. *
  26. * @param {CompressedTexture} texture - The compressed texture.
  27. * @param {number} [maxTextureSize=Infinity] - The maximum size of the uncompressed texture.
  28. * @param {?WebGLRenderer} [renderer=null] - A reference to a renderer.
  29. * @return {CanvasTexture} The uncompressed texture.
  30. */
  31. export function decompress( texture, maxTextureSize = Infinity, renderer = null ) {
  32. if ( ! fullscreenQuadGeometry ) fullscreenQuadGeometry = new PlaneGeometry( 2, 2, 1, 1 );
  33. if ( ! fullscreenQuadMaterial ) fullscreenQuadMaterial = new ShaderMaterial( {
  34. uniforms: { blitTexture: new Uniform( texture ) },
  35. vertexShader: `
  36. varying vec2 vUv;
  37. void main(){
  38. vUv = uv;
  39. gl_Position = vec4(position.xy * 1.0,0.,.999999);
  40. }`,
  41. fragmentShader: `
  42. uniform sampler2D blitTexture;
  43. varying vec2 vUv;
  44. void main(){
  45. gl_FragColor = vec4(vUv.xy, 0, 1);
  46. #ifdef IS_SRGB
  47. gl_FragColor = sRGBTransferOETF( texture2D( blitTexture, vUv) );
  48. #else
  49. gl_FragColor = texture2D( blitTexture, vUv);
  50. #endif
  51. }`
  52. } );
  53. fullscreenQuadMaterial.uniforms.blitTexture.value = texture;
  54. fullscreenQuadMaterial.defines.IS_SRGB = texture.colorSpace == SRGBColorSpace;
  55. fullscreenQuadMaterial.needsUpdate = true;
  56. if ( ! fullscreenQuad ) {
  57. fullscreenQuad = new Mesh( fullscreenQuadGeometry, fullscreenQuadMaterial );
  58. fullscreenQuad.frustumCulled = false;
  59. }
  60. const _camera = new PerspectiveCamera();
  61. const _scene = new Scene();
  62. _scene.add( fullscreenQuad );
  63. if ( renderer === null ) {
  64. renderer = _renderer = new WebGLRenderer( { antialias: false } );
  65. }
  66. const width = Math.min( texture.image.width, maxTextureSize );
  67. const height = Math.min( texture.image.height, maxTextureSize );
  68. renderer.setSize( width, height );
  69. renderer.clear();
  70. renderer.render( _scene, _camera );
  71. const canvas = document.createElement( 'canvas' );
  72. const context = canvas.getContext( '2d' );
  73. canvas.width = width;
  74. canvas.height = height;
  75. context.drawImage( renderer.domElement, 0, 0, width, height );
  76. const readableTexture = new CanvasTexture( canvas );
  77. readableTexture.minFilter = texture.minFilter;
  78. readableTexture.magFilter = texture.magFilter;
  79. readableTexture.wrapS = texture.wrapS;
  80. readableTexture.wrapT = texture.wrapT;
  81. readableTexture.colorSpace = texture.colorSpace;
  82. readableTexture.name = texture.name;
  83. if ( _renderer ) {
  84. _renderer.forceContextLoss();
  85. _renderer.dispose();
  86. _renderer = null;
  87. }
  88. return readableTexture;
  89. }