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; | ||
|  | 
 | ||
|  | } |