TextureUtils.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import {
  2. PlaneGeometry,
  3. ShaderMaterial,
  4. Uniform,
  5. Mesh,
  6. PerspectiveCamera,
  7. Scene,
  8. WebGLRenderer,
  9. CanvasTexture,
  10. SRGBColorSpace
  11. } from 'three';
  12. let _renderer;
  13. let fullscreenQuadGeometry;
  14. let fullscreenQuadMaterial;
  15. let fullscreenQuad;
  16. export function decompress( texture, maxTextureSize = Infinity, renderer = null ) {
  17. if ( ! fullscreenQuadGeometry ) fullscreenQuadGeometry = new PlaneGeometry( 2, 2, 1, 1 );
  18. if ( ! fullscreenQuadMaterial ) fullscreenQuadMaterial = new ShaderMaterial( {
  19. uniforms: { blitTexture: new Uniform( texture ) },
  20. vertexShader: `
  21. varying vec2 vUv;
  22. void main(){
  23. vUv = uv;
  24. gl_Position = vec4(position.xy * 1.0,0.,.999999);
  25. }`,
  26. fragmentShader: `
  27. uniform sampler2D blitTexture;
  28. varying vec2 vUv;
  29. void main(){
  30. gl_FragColor = vec4(vUv.xy, 0, 1);
  31. #ifdef IS_SRGB
  32. gl_FragColor = LinearTosRGB( texture2D( blitTexture, vUv) );
  33. #else
  34. gl_FragColor = texture2D( blitTexture, vUv);
  35. #endif
  36. }`
  37. } );
  38. fullscreenQuadMaterial.uniforms.blitTexture.value = texture;
  39. fullscreenQuadMaterial.defines.IS_SRGB = texture.colorSpace == SRGBColorSpace;
  40. fullscreenQuadMaterial.needsUpdate = true;
  41. if ( ! fullscreenQuad ) {
  42. fullscreenQuad = new Mesh( fullscreenQuadGeometry, fullscreenQuadMaterial );
  43. fullscreenQuad.frustumCulled = false;
  44. }
  45. const _camera = new PerspectiveCamera();
  46. const _scene = new Scene();
  47. _scene.add( fullscreenQuad );
  48. if ( renderer === null ) {
  49. renderer = _renderer = new WebGLRenderer( { antialias: false } );
  50. }
  51. const width = Math.min( texture.image.width, maxTextureSize );
  52. const height = Math.min( texture.image.height, maxTextureSize );
  53. renderer.setSize( width, height );
  54. renderer.clear();
  55. renderer.render( _scene, _camera );
  56. const canvas = document.createElement( 'canvas' );
  57. const context = canvas.getContext( '2d' );
  58. canvas.width = width;
  59. canvas.height = height;
  60. context.drawImage( renderer.domElement, 0, 0, width, height );
  61. const readableTexture = new CanvasTexture( canvas );
  62. readableTexture.minFilter = texture.minFilter;
  63. readableTexture.magFilter = texture.magFilter;
  64. readableTexture.wrapS = texture.wrapS;
  65. readableTexture.wrapT = texture.wrapT;
  66. readableTexture.name = texture.name;
  67. if ( _renderer ) {
  68. _renderer.forceContextLoss();
  69. _renderer.dispose();
  70. _renderer = null;
  71. }
  72. return readableTexture;
  73. }