99 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import {
 | |
| 	PlaneGeometry,
 | |
| 	ShaderMaterial,
 | |
| 	Uniform,
 | |
| 	Mesh,
 | |
| 	PerspectiveCamera,
 | |
| 	Scene,
 | |
| 	WebGLRenderer,
 | |
| 	CanvasTexture,
 | |
| 	SRGBColorSpace
 | |
| } from 'three';
 | |
| 
 | |
| let _renderer;
 | |
| let fullscreenQuadGeometry;
 | |
| let fullscreenQuadMaterial;
 | |
| let fullscreenQuad;
 | |
| 
 | |
| export function decompress( texture, maxTextureSize = Infinity, renderer = null ) {
 | |
| 
 | |
| 	if ( ! fullscreenQuadGeometry ) fullscreenQuadGeometry = new PlaneGeometry( 2, 2, 1, 1 );
 | |
| 	if ( ! fullscreenQuadMaterial ) fullscreenQuadMaterial = new ShaderMaterial( {
 | |
| 		uniforms: { blitTexture: new Uniform( texture ) },
 | |
| 		vertexShader: `
 | |
| 			varying vec2 vUv;
 | |
| 			void main(){
 | |
| 				vUv = uv;
 | |
| 				gl_Position = vec4(position.xy * 1.0,0.,.999999);
 | |
| 			}`,
 | |
| 		fragmentShader: `
 | |
| 			uniform sampler2D blitTexture; 
 | |
| 			varying vec2 vUv;
 | |
| 
 | |
| 			void main(){ 
 | |
| 				gl_FragColor = vec4(vUv.xy, 0, 1);
 | |
| 				
 | |
| 				#ifdef IS_SRGB
 | |
| 				gl_FragColor = LinearTosRGB( texture2D( blitTexture, vUv) );
 | |
| 				#else
 | |
| 				gl_FragColor = texture2D( blitTexture, vUv);
 | |
| 				#endif
 | |
| 			}`
 | |
| 	} );
 | |
| 
 | |
| 	fullscreenQuadMaterial.uniforms.blitTexture.value = texture;
 | |
| 	fullscreenQuadMaterial.defines.IS_SRGB = texture.colorSpace == SRGBColorSpace;
 | |
| 	fullscreenQuadMaterial.needsUpdate = true;
 | |
| 
 | |
| 	if ( ! fullscreenQuad ) {
 | |
| 
 | |
| 		fullscreenQuad = new Mesh( fullscreenQuadGeometry, fullscreenQuadMaterial );
 | |
| 		fullscreenQuad.frustumCulled = false;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	const _camera = new PerspectiveCamera();
 | |
| 	const _scene = new Scene();
 | |
| 	_scene.add( fullscreenQuad );
 | |
| 
 | |
| 	if ( renderer === null ) {
 | |
| 
 | |
| 		renderer = _renderer = new WebGLRenderer( { antialias: false } );
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	const width = Math.min( texture.image.width, maxTextureSize );
 | |
| 	const height = Math.min( texture.image.height, maxTextureSize );
 | |
| 
 | |
| 	renderer.setSize( width, height );
 | |
| 	renderer.clear();
 | |
| 	renderer.render( _scene, _camera );
 | |
| 
 | |
| 	const canvas = document.createElement( 'canvas' );
 | |
| 	const context = canvas.getContext( '2d' );
 | |
| 
 | |
| 	canvas.width = width;
 | |
| 	canvas.height = height;
 | |
| 
 | |
| 	context.drawImage( renderer.domElement, 0, 0, width, height );
 | |
| 
 | |
| 	const readableTexture = new CanvasTexture( canvas );
 | |
| 
 | |
| 	readableTexture.minFilter = texture.minFilter;
 | |
| 	readableTexture.magFilter = texture.magFilter;
 | |
| 	readableTexture.wrapS = texture.wrapS;
 | |
| 	readableTexture.wrapT = texture.wrapT;
 | |
| 	readableTexture.name = texture.name;
 | |
| 
 | |
| 	if ( _renderer ) {
 | |
| 
 | |
| 		_renderer.forceContextLoss();
 | |
| 		_renderer.dispose();
 | |
| 		_renderer = null;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	return readableTexture;
 | |
| 
 | |
| }
 |