File size: 2,657 Bytes
2b7aae2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
100
import { CubeReflectionMapping, CubeRefractionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping } from '../../constants.js';
import { PMREMGenerator } from '../../extras/PMREMGenerator.js';

function WebGLCubeUVMaps(renderer) {
	let cubeUVmaps = new WeakMap();

	let pmremGenerator = null;

	function get(texture) {
		if (texture && texture.isTexture) {
			const mapping = texture.mapping;

			const isEquirectMap = mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping;
			const isCubeMap = mapping === CubeReflectionMapping || mapping === CubeRefractionMapping;

			// equirect/cube map to cubeUV conversion

			if (isEquirectMap || isCubeMap) {
				if (texture.isRenderTargetTexture && texture.needsPMREMUpdate === true) {
					texture.needsPMREMUpdate = false;

					let renderTarget = cubeUVmaps.get(texture);

					if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer);

					renderTarget = isEquirectMap
						? pmremGenerator.fromEquirectangular(texture, renderTarget)
						: pmremGenerator.fromCubemap(texture, renderTarget);
					cubeUVmaps.set(texture, renderTarget);

					return renderTarget.texture;
				} else {
					if (cubeUVmaps.has(texture)) {
						return cubeUVmaps.get(texture).texture;
					} else {
						const image = texture.image;

						if ((isEquirectMap && image && image.height > 0) || (isCubeMap && image && isCubeTextureComplete(image))) {
							if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer);

							const renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture) : pmremGenerator.fromCubemap(texture);
							cubeUVmaps.set(texture, renderTarget);

							texture.addEventListener('dispose', onTextureDispose);

							return renderTarget.texture;
						} else {
							// image not yet ready. try the conversion next frame

							return null;
						}
					}
				}
			}
		}

		return texture;
	}

	function isCubeTextureComplete(image) {
		let count = 0;
		const length = 6;

		for (let i = 0; i < length; i++) {
			if (image[i] !== undefined) count++;
		}

		return count === length;
	}

	function onTextureDispose(event) {
		const texture = event.target;

		texture.removeEventListener('dispose', onTextureDispose);

		const cubemapUV = cubeUVmaps.get(texture);

		if (cubemapUV !== undefined) {
			cubeUVmaps.delete(texture);
			cubemapUV.dispose();
		}
	}

	function dispose() {
		cubeUVmaps = new WeakMap();

		if (pmremGenerator !== null) {
			pmremGenerator.dispose();
			pmremGenerator = null;
		}
	}

	return {
		get: get,
		dispose: dispose,
	};
}

export { WebGLCubeUVMaps };