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