-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
/
WebGLTextureUtils.js
99 lines (74 loc) · 2.36 KB
/
WebGLTextureUtils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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 = sRGBTransferOETF( 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.colorSpace = texture.colorSpace;
readableTexture.name = texture.name;
if ( _renderer ) {
_renderer.forceContextLoss();
_renderer.dispose();
_renderer = null;
}
return readableTexture;
}