three-gpu-pathtracer 0.0.13 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +981 -961
- package/build/index.module.js +6965 -6508
- package/build/index.module.js.map +1 -1
- package/build/index.umd.cjs +6959 -6505
- package/build/index.umd.cjs.map +1 -1
- package/package.json +73 -73
- package/src/core/DynamicPathTracingSceneGenerator.js +119 -119
- package/src/core/MaterialReducer.js +256 -256
- package/src/core/PathTracingRenderer.js +346 -346
- package/src/core/PathTracingSceneGenerator.js +69 -69
- package/src/core/QuiltPathTracingRenderer.js +223 -223
- package/src/index.js +36 -40
- package/src/materials/MaterialBase.js +56 -56
- package/src/materials/{GraphMaterial.js → debug/GraphMaterial.js} +243 -243
- package/src/materials/{AlphaDisplayMaterial.js → fullscreen/AlphaDisplayMaterial.js} +48 -48
- package/src/materials/{BlendMaterial.js → fullscreen/BlendMaterial.js} +67 -67
- package/src/materials/{DenoiseMaterial.js → fullscreen/DenoiseMaterial.js} +142 -142
- package/src/materials/{LambertPathTracingMaterial.js → pathtracing/LambertPathTracingMaterial.js} +296 -285
- package/src/materials/pathtracing/PhysicalPathTracingMaterial.js +635 -0
- package/src/materials/pathtracing/glsl/attenuateHit.glsl.js +179 -0
- package/src/materials/pathtracing/glsl/cameraUtils.glsl.js +81 -0
- package/src/materials/pathtracing/glsl/getSurfaceRecord.glsl.js +317 -0
- package/src/materials/pathtracing/glsl/traceScene.glsl.js +54 -0
- package/src/materials/{AmbientOcclusionMaterial.js → surface/AmbientOcclusionMaterial.js} +207 -199
- package/src/materials/surface/FogVolumeMaterial.js +23 -0
- package/src/objects/EquirectCamera.js +13 -13
- package/src/objects/PhysicalCamera.js +28 -28
- package/src/objects/PhysicalSpotLight.js +14 -14
- package/src/objects/ShapedAreaLight.js +12 -12
- package/src/shader/bsdf/bsdfSampling.glsl.js +490 -0
- package/src/shader/bsdf/fog.glsl.js +23 -0
- package/src/shader/bsdf/ggx.glsl.js +102 -0
- package/src/shader/bsdf/iridescence.glsl.js +135 -0
- package/src/shader/bsdf/sheen.glsl.js +98 -0
- package/src/shader/{shaderLayerTexelFetchFunctions.js → common/arraySamplerTexelFetch.glsl.js} +25 -25
- package/src/shader/common/bvhAnyHit.glsl.js +76 -0
- package/src/shader/common/fresnel.glsl.js +98 -0
- package/src/shader/common/intersectShapes.glsl.js +62 -0
- package/src/shader/common/math.glsl.js +81 -0
- package/src/shader/common/utils.glsl.js +116 -0
- package/src/shader/{shaderRandFunctions.js → rand/pcg.glsl.js} +57 -57
- package/src/shader/{shaderSobolSampling.js → rand/sobol.glsl.js} +256 -256
- package/src/shader/sampling/equirectSampling.glsl.js +62 -0
- package/src/shader/sampling/lightSampling.glsl.js +223 -0
- package/src/shader/sampling/shapeSampling.glsl.js +86 -0
- package/src/shader/structs/cameraStruct.glsl.js +13 -0
- package/src/shader/structs/equirectStruct.glsl.js +14 -0
- package/src/shader/structs/fogMaterialBvh.glsl.js +62 -0
- package/src/shader/structs/lightsStruct.glsl.js +78 -0
- package/src/shader/{shaderStructs.js → structs/materialStruct.glsl.js} +207 -327
- package/src/textures/GradientEquirectTexture.js +35 -35
- package/src/textures/ProceduralEquirectTexture.js +75 -75
- package/src/uniforms/AttributesTextureArray.js +35 -35
- package/src/uniforms/EquirectHdrInfoUniform.js +277 -273
- package/src/uniforms/FloatAttributeTextureArray.js +169 -169
- package/src/uniforms/IESProfilesTexture.js +100 -100
- package/src/uniforms/LightsInfoUniformStruct.js +212 -212
- package/src/uniforms/MaterialsTexture.js +503 -426
- package/src/uniforms/PhysicalCameraUniform.js +36 -36
- package/src/uniforms/RenderTarget2DArray.js +97 -97
- package/src/uniforms/utils.js +30 -30
- package/src/utils/BlurredEnvMapGenerator.js +116 -116
- package/src/utils/GeometryPreparationUtils.js +214 -214
- package/src/utils/IESLoader.js +325 -325
- package/src/utils/SobolNumberMapGenerator.js +80 -80
- package/src/utils/UVUnwrapper.js +101 -101
- package/src/utils/macroify.js +9 -0
- package/src/workers/PathTracingSceneWorker.js +42 -42
- package/src/materials/PhysicalPathTracingMaterial.js +0 -1013
- package/src/shader/shaderBvhAnyHit.js +0 -76
- package/src/shader/shaderEnvMapSampling.js +0 -58
- package/src/shader/shaderGGXFunctions.js +0 -100
- package/src/shader/shaderIridescenceFunctions.js +0 -135
- package/src/shader/shaderLightSampling.js +0 -229
- package/src/shader/shaderMaterialSampling.js +0 -510
- package/src/shader/shaderSheenFunctions.js +0 -98
- package/src/shader/shaderUtils.js +0 -377
|
@@ -1,169 +1,169 @@
|
|
|
1
|
-
import { DataArrayTexture, FloatType, RGBAFormat } from 'three';
|
|
2
|
-
import { FloatVertexAttributeTexture } from 'three-mesh-bvh';
|
|
3
|
-
|
|
4
|
-
function copyArrayToArray( fromArray, fromStride, toArray, toStride, offset ) {
|
|
5
|
-
|
|
6
|
-
if ( fromStride > toStride ) {
|
|
7
|
-
|
|
8
|
-
throw new Error();
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// scale non-float values to their normalized range
|
|
13
|
-
const count = fromArray.length / fromStride;
|
|
14
|
-
const bpe = fromArray.constructor.BYTES_PER_ELEMENT * 8;
|
|
15
|
-
let maxValue = 1.0;
|
|
16
|
-
switch ( fromArray.constructor ) {
|
|
17
|
-
|
|
18
|
-
case Uint8Array:
|
|
19
|
-
case Uint16Array:
|
|
20
|
-
case Uint32Array:
|
|
21
|
-
maxValue = 2 ** bpe - 1;
|
|
22
|
-
break;
|
|
23
|
-
|
|
24
|
-
case Int8Array:
|
|
25
|
-
case Int16Array:
|
|
26
|
-
case Int32Array:
|
|
27
|
-
maxValue = 2 ** ( bpe - 1 ) - 1;
|
|
28
|
-
break;
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
for ( let i = 0; i < count; i ++ ) {
|
|
33
|
-
|
|
34
|
-
const i4 = 4 * i;
|
|
35
|
-
const is = fromStride * i;
|
|
36
|
-
for ( let j = 0; j < toStride; j ++ ) {
|
|
37
|
-
|
|
38
|
-
toArray[ offset + i4 + j ] = fromStride >= j + 1 ? fromArray[ is + j ] / maxValue : 0;
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export class FloatAttributeTextureArray extends DataArrayTexture {
|
|
47
|
-
|
|
48
|
-
constructor() {
|
|
49
|
-
|
|
50
|
-
super();
|
|
51
|
-
this._textures = [];
|
|
52
|
-
this.type = FloatType;
|
|
53
|
-
this.format = RGBAFormat;
|
|
54
|
-
this.internalFormat = 'RGBA32F';
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
updateAttribute( index, attr ) {
|
|
59
|
-
|
|
60
|
-
// update the texture
|
|
61
|
-
const tex = this._textures[ index ];
|
|
62
|
-
tex.updateFrom( attr );
|
|
63
|
-
|
|
64
|
-
// ensure compatibility
|
|
65
|
-
const baseImage = tex.image;
|
|
66
|
-
const image = this.image;
|
|
67
|
-
if ( baseImage.width !== image.width || baseImage.height !== image.height ) {
|
|
68
|
-
|
|
69
|
-
throw new Error( 'FloatAttributeTextureArray: Attribute must be the same dimensions when updating single layer.' );
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// update the image
|
|
74
|
-
const { width, height, data } = image;
|
|
75
|
-
const length = width * height * 4;
|
|
76
|
-
const offset = length * index;
|
|
77
|
-
let itemSize = attr.itemSize;
|
|
78
|
-
if ( itemSize === 3 ) {
|
|
79
|
-
|
|
80
|
-
itemSize = 4;
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// copy the data
|
|
85
|
-
copyArrayToArray( tex.image.data, itemSize, data, 4, offset );
|
|
86
|
-
|
|
87
|
-
this.dispose();
|
|
88
|
-
this.needsUpdate = true;
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
setAttributes( attrs ) {
|
|
93
|
-
|
|
94
|
-
// ensure the attribute count
|
|
95
|
-
const itemCount = attrs[ 0 ].count;
|
|
96
|
-
const attrsLength = attrs.length;
|
|
97
|
-
for ( let i = 0, l = attrsLength; i < l; i ++ ) {
|
|
98
|
-
|
|
99
|
-
if ( attrs[ i ].count !== itemCount ) {
|
|
100
|
-
|
|
101
|
-
throw new Error( 'FloatAttributeTextureArray: All attributes must have the same item count.' );
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// initialize all textures
|
|
108
|
-
const textures = this._textures;
|
|
109
|
-
while ( textures.length < attrsLength ) {
|
|
110
|
-
|
|
111
|
-
const tex = new FloatVertexAttributeTexture();
|
|
112
|
-
textures.push( tex );
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
while ( textures.length > attrsLength ) {
|
|
117
|
-
|
|
118
|
-
textures.pop();
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// update all textures
|
|
123
|
-
for ( let i = 0, l = attrsLength; i < l; i ++ ) {
|
|
124
|
-
|
|
125
|
-
textures[ i ].updateFrom( attrs[ i ] );
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// determine if we need to create a new array
|
|
130
|
-
const baseTexture = textures[ 0 ];
|
|
131
|
-
const baseImage = baseTexture.image;
|
|
132
|
-
const image = this.image;
|
|
133
|
-
|
|
134
|
-
if ( baseImage.width !== image.width || baseImage.height !== image.height || baseImage.depth !== attrsLength ) {
|
|
135
|
-
|
|
136
|
-
image.width = baseImage.width;
|
|
137
|
-
image.height = baseImage.height;
|
|
138
|
-
image.depth = attrsLength;
|
|
139
|
-
image.data = new Float32Array( image.width * image.height * image.depth * 4 );
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// copy the other texture data into the data array texture
|
|
144
|
-
const { data, width, height } = image;
|
|
145
|
-
for ( let i = 0, l = attrsLength; i < l; i ++ ) {
|
|
146
|
-
|
|
147
|
-
const tex = textures[ i ];
|
|
148
|
-
const length = width * height * 4;
|
|
149
|
-
const offset = length * i;
|
|
150
|
-
|
|
151
|
-
let itemSize = attrs[ i ].itemSize;
|
|
152
|
-
if ( itemSize === 3 ) {
|
|
153
|
-
|
|
154
|
-
itemSize = 4;
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
copyArrayToArray( tex.image.data, itemSize, data, 4, offset );
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// reset the texture
|
|
163
|
-
this.dispose();
|
|
164
|
-
this.needsUpdate = true;
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
1
|
+
import { DataArrayTexture, FloatType, RGBAFormat } from 'three';
|
|
2
|
+
import { FloatVertexAttributeTexture } from 'three-mesh-bvh';
|
|
3
|
+
|
|
4
|
+
function copyArrayToArray( fromArray, fromStride, toArray, toStride, offset ) {
|
|
5
|
+
|
|
6
|
+
if ( fromStride > toStride ) {
|
|
7
|
+
|
|
8
|
+
throw new Error();
|
|
9
|
+
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// scale non-float values to their normalized range
|
|
13
|
+
const count = fromArray.length / fromStride;
|
|
14
|
+
const bpe = fromArray.constructor.BYTES_PER_ELEMENT * 8;
|
|
15
|
+
let maxValue = 1.0;
|
|
16
|
+
switch ( fromArray.constructor ) {
|
|
17
|
+
|
|
18
|
+
case Uint8Array:
|
|
19
|
+
case Uint16Array:
|
|
20
|
+
case Uint32Array:
|
|
21
|
+
maxValue = 2 ** bpe - 1;
|
|
22
|
+
break;
|
|
23
|
+
|
|
24
|
+
case Int8Array:
|
|
25
|
+
case Int16Array:
|
|
26
|
+
case Int32Array:
|
|
27
|
+
maxValue = 2 ** ( bpe - 1 ) - 1;
|
|
28
|
+
break;
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
for ( let i = 0; i < count; i ++ ) {
|
|
33
|
+
|
|
34
|
+
const i4 = 4 * i;
|
|
35
|
+
const is = fromStride * i;
|
|
36
|
+
for ( let j = 0; j < toStride; j ++ ) {
|
|
37
|
+
|
|
38
|
+
toArray[ offset + i4 + j ] = fromStride >= j + 1 ? fromArray[ is + j ] / maxValue : 0;
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class FloatAttributeTextureArray extends DataArrayTexture {
|
|
47
|
+
|
|
48
|
+
constructor() {
|
|
49
|
+
|
|
50
|
+
super();
|
|
51
|
+
this._textures = [];
|
|
52
|
+
this.type = FloatType;
|
|
53
|
+
this.format = RGBAFormat;
|
|
54
|
+
this.internalFormat = 'RGBA32F';
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
updateAttribute( index, attr ) {
|
|
59
|
+
|
|
60
|
+
// update the texture
|
|
61
|
+
const tex = this._textures[ index ];
|
|
62
|
+
tex.updateFrom( attr );
|
|
63
|
+
|
|
64
|
+
// ensure compatibility
|
|
65
|
+
const baseImage = tex.image;
|
|
66
|
+
const image = this.image;
|
|
67
|
+
if ( baseImage.width !== image.width || baseImage.height !== image.height ) {
|
|
68
|
+
|
|
69
|
+
throw new Error( 'FloatAttributeTextureArray: Attribute must be the same dimensions when updating single layer.' );
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// update the image
|
|
74
|
+
const { width, height, data } = image;
|
|
75
|
+
const length = width * height * 4;
|
|
76
|
+
const offset = length * index;
|
|
77
|
+
let itemSize = attr.itemSize;
|
|
78
|
+
if ( itemSize === 3 ) {
|
|
79
|
+
|
|
80
|
+
itemSize = 4;
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// copy the data
|
|
85
|
+
copyArrayToArray( tex.image.data, itemSize, data, 4, offset );
|
|
86
|
+
|
|
87
|
+
this.dispose();
|
|
88
|
+
this.needsUpdate = true;
|
|
89
|
+
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
setAttributes( attrs ) {
|
|
93
|
+
|
|
94
|
+
// ensure the attribute count
|
|
95
|
+
const itemCount = attrs[ 0 ].count;
|
|
96
|
+
const attrsLength = attrs.length;
|
|
97
|
+
for ( let i = 0, l = attrsLength; i < l; i ++ ) {
|
|
98
|
+
|
|
99
|
+
if ( attrs[ i ].count !== itemCount ) {
|
|
100
|
+
|
|
101
|
+
throw new Error( 'FloatAttributeTextureArray: All attributes must have the same item count.' );
|
|
102
|
+
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// initialize all textures
|
|
108
|
+
const textures = this._textures;
|
|
109
|
+
while ( textures.length < attrsLength ) {
|
|
110
|
+
|
|
111
|
+
const tex = new FloatVertexAttributeTexture();
|
|
112
|
+
textures.push( tex );
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
while ( textures.length > attrsLength ) {
|
|
117
|
+
|
|
118
|
+
textures.pop();
|
|
119
|
+
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// update all textures
|
|
123
|
+
for ( let i = 0, l = attrsLength; i < l; i ++ ) {
|
|
124
|
+
|
|
125
|
+
textures[ i ].updateFrom( attrs[ i ] );
|
|
126
|
+
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// determine if we need to create a new array
|
|
130
|
+
const baseTexture = textures[ 0 ];
|
|
131
|
+
const baseImage = baseTexture.image;
|
|
132
|
+
const image = this.image;
|
|
133
|
+
|
|
134
|
+
if ( baseImage.width !== image.width || baseImage.height !== image.height || baseImage.depth !== attrsLength ) {
|
|
135
|
+
|
|
136
|
+
image.width = baseImage.width;
|
|
137
|
+
image.height = baseImage.height;
|
|
138
|
+
image.depth = attrsLength;
|
|
139
|
+
image.data = new Float32Array( image.width * image.height * image.depth * 4 );
|
|
140
|
+
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// copy the other texture data into the data array texture
|
|
144
|
+
const { data, width, height } = image;
|
|
145
|
+
for ( let i = 0, l = attrsLength; i < l; i ++ ) {
|
|
146
|
+
|
|
147
|
+
const tex = textures[ i ];
|
|
148
|
+
const length = width * height * 4;
|
|
149
|
+
const offset = length * i;
|
|
150
|
+
|
|
151
|
+
let itemSize = attrs[ i ].itemSize;
|
|
152
|
+
if ( itemSize === 3 ) {
|
|
153
|
+
|
|
154
|
+
itemSize = 4;
|
|
155
|
+
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
copyArrayToArray( tex.image.data, itemSize, data, 4, offset );
|
|
159
|
+
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// reset the texture
|
|
163
|
+
this.dispose();
|
|
164
|
+
this.needsUpdate = true;
|
|
165
|
+
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
}
|
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ClampToEdgeWrapping,
|
|
3
|
-
Color,
|
|
4
|
-
FloatType,
|
|
5
|
-
LinearFilter,
|
|
6
|
-
MeshBasicMaterial,
|
|
7
|
-
NoToneMapping,
|
|
8
|
-
RGBAFormat,
|
|
9
|
-
WebGLArrayRenderTarget,
|
|
10
|
-
} from 'three';
|
|
11
|
-
import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';
|
|
12
|
-
import { IESLoader } from '../utils/IESLoader.js';
|
|
13
|
-
|
|
14
|
-
const prevColor = new Color();
|
|
15
|
-
export class IESProfilesTexture extends WebGLArrayRenderTarget {
|
|
16
|
-
|
|
17
|
-
constructor( ...args ) {
|
|
18
|
-
|
|
19
|
-
super( ...args );
|
|
20
|
-
|
|
21
|
-
const tex = this.texture;
|
|
22
|
-
tex.format = RGBAFormat;
|
|
23
|
-
tex.type = FloatType;
|
|
24
|
-
tex.minFilter = LinearFilter;
|
|
25
|
-
tex.magFilter = LinearFilter;
|
|
26
|
-
tex.wrapS = ClampToEdgeWrapping;
|
|
27
|
-
tex.wrapT = ClampToEdgeWrapping;
|
|
28
|
-
tex.generateMipmaps = false;
|
|
29
|
-
|
|
30
|
-
tex.updateFrom = ( ...args ) => {
|
|
31
|
-
|
|
32
|
-
this.updateFrom( ...args );
|
|
33
|
-
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const fsQuad = new FullScreenQuad( new MeshBasicMaterial() );
|
|
37
|
-
this.fsQuad = fsQuad;
|
|
38
|
-
|
|
39
|
-
this.iesLoader = new IESLoader();
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async updateFrom( renderer, textures ) {
|
|
44
|
-
|
|
45
|
-
// save previous renderer state
|
|
46
|
-
const prevRenderTarget = renderer.getRenderTarget();
|
|
47
|
-
const prevToneMapping = renderer.toneMapping;
|
|
48
|
-
const prevAlpha = renderer.getClearAlpha();
|
|
49
|
-
renderer.getClearColor( prevColor );
|
|
50
|
-
|
|
51
|
-
// resize the render target and ensure we don't have an empty texture
|
|
52
|
-
// render target depth must be >= 1 to avoid unbound texture error on android devices
|
|
53
|
-
const depth = textures.length || 1;
|
|
54
|
-
this.setSize( 360, 180, depth );
|
|
55
|
-
renderer.setClearColor( 0, 0 );
|
|
56
|
-
renderer.toneMapping = NoToneMapping;
|
|
57
|
-
|
|
58
|
-
// render each texture into each layer of the target
|
|
59
|
-
const fsQuad = this.fsQuad;
|
|
60
|
-
for ( let i = 0, l = depth; i < l; i ++ ) {
|
|
61
|
-
|
|
62
|
-
const texture = textures[ i ];
|
|
63
|
-
if ( texture ) {
|
|
64
|
-
|
|
65
|
-
// revert to default texture transform before rendering
|
|
66
|
-
texture.matrixAutoUpdate = false;
|
|
67
|
-
texture.matrix.identity();
|
|
68
|
-
|
|
69
|
-
fsQuad.material.map = texture;
|
|
70
|
-
fsQuad.material.transparent = true;
|
|
71
|
-
|
|
72
|
-
renderer.setRenderTarget( this, i );
|
|
73
|
-
fsQuad.render( renderer );
|
|
74
|
-
|
|
75
|
-
// restore custom texture transform
|
|
76
|
-
texture.updateMatrix();
|
|
77
|
-
texture.matrixAutoUpdate = true;
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// reset the renderer
|
|
84
|
-
fsQuad.material.map = null;
|
|
85
|
-
renderer.setClearColor( prevColor, prevAlpha );
|
|
86
|
-
renderer.setRenderTarget( prevRenderTarget );
|
|
87
|
-
renderer.toneMapping = prevToneMapping;
|
|
88
|
-
|
|
89
|
-
fsQuad.dispose();
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
dispose() {
|
|
94
|
-
|
|
95
|
-
super.dispose();
|
|
96
|
-
this.fsQuad.dispose();
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
ClampToEdgeWrapping,
|
|
3
|
+
Color,
|
|
4
|
+
FloatType,
|
|
5
|
+
LinearFilter,
|
|
6
|
+
MeshBasicMaterial,
|
|
7
|
+
NoToneMapping,
|
|
8
|
+
RGBAFormat,
|
|
9
|
+
WebGLArrayRenderTarget,
|
|
10
|
+
} from 'three';
|
|
11
|
+
import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';
|
|
12
|
+
import { IESLoader } from '../utils/IESLoader.js';
|
|
13
|
+
|
|
14
|
+
const prevColor = new Color();
|
|
15
|
+
export class IESProfilesTexture extends WebGLArrayRenderTarget {
|
|
16
|
+
|
|
17
|
+
constructor( ...args ) {
|
|
18
|
+
|
|
19
|
+
super( ...args );
|
|
20
|
+
|
|
21
|
+
const tex = this.texture;
|
|
22
|
+
tex.format = RGBAFormat;
|
|
23
|
+
tex.type = FloatType;
|
|
24
|
+
tex.minFilter = LinearFilter;
|
|
25
|
+
tex.magFilter = LinearFilter;
|
|
26
|
+
tex.wrapS = ClampToEdgeWrapping;
|
|
27
|
+
tex.wrapT = ClampToEdgeWrapping;
|
|
28
|
+
tex.generateMipmaps = false;
|
|
29
|
+
|
|
30
|
+
tex.updateFrom = ( ...args ) => {
|
|
31
|
+
|
|
32
|
+
this.updateFrom( ...args );
|
|
33
|
+
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const fsQuad = new FullScreenQuad( new MeshBasicMaterial() );
|
|
37
|
+
this.fsQuad = fsQuad;
|
|
38
|
+
|
|
39
|
+
this.iesLoader = new IESLoader();
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async updateFrom( renderer, textures ) {
|
|
44
|
+
|
|
45
|
+
// save previous renderer state
|
|
46
|
+
const prevRenderTarget = renderer.getRenderTarget();
|
|
47
|
+
const prevToneMapping = renderer.toneMapping;
|
|
48
|
+
const prevAlpha = renderer.getClearAlpha();
|
|
49
|
+
renderer.getClearColor( prevColor );
|
|
50
|
+
|
|
51
|
+
// resize the render target and ensure we don't have an empty texture
|
|
52
|
+
// render target depth must be >= 1 to avoid unbound texture error on android devices
|
|
53
|
+
const depth = textures.length || 1;
|
|
54
|
+
this.setSize( 360, 180, depth );
|
|
55
|
+
renderer.setClearColor( 0, 0 );
|
|
56
|
+
renderer.toneMapping = NoToneMapping;
|
|
57
|
+
|
|
58
|
+
// render each texture into each layer of the target
|
|
59
|
+
const fsQuad = this.fsQuad;
|
|
60
|
+
for ( let i = 0, l = depth; i < l; i ++ ) {
|
|
61
|
+
|
|
62
|
+
const texture = textures[ i ];
|
|
63
|
+
if ( texture ) {
|
|
64
|
+
|
|
65
|
+
// revert to default texture transform before rendering
|
|
66
|
+
texture.matrixAutoUpdate = false;
|
|
67
|
+
texture.matrix.identity();
|
|
68
|
+
|
|
69
|
+
fsQuad.material.map = texture;
|
|
70
|
+
fsQuad.material.transparent = true;
|
|
71
|
+
|
|
72
|
+
renderer.setRenderTarget( this, i );
|
|
73
|
+
fsQuad.render( renderer );
|
|
74
|
+
|
|
75
|
+
// restore custom texture transform
|
|
76
|
+
texture.updateMatrix();
|
|
77
|
+
texture.matrixAutoUpdate = true;
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// reset the renderer
|
|
84
|
+
fsQuad.material.map = null;
|
|
85
|
+
renderer.setClearColor( prevColor, prevAlpha );
|
|
86
|
+
renderer.setRenderTarget( prevRenderTarget );
|
|
87
|
+
renderer.toneMapping = prevToneMapping;
|
|
88
|
+
|
|
89
|
+
fsQuad.dispose();
|
|
90
|
+
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
dispose() {
|
|
94
|
+
|
|
95
|
+
super.dispose();
|
|
96
|
+
this.fsQuad.dispose();
|
|
97
|
+
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
}
|