three-gpu-pathtracer 0.0.20 → 0.0.21
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/README.md +111 -464
- package/build/index.module.js +5691 -5312
- package/build/index.module.js.map +1 -1
- package/build/index.umd.cjs +5369 -5003
- package/build/index.umd.cjs.map +1 -1
- package/package.json +12 -6
- package/src/core/PathTracingRenderer.js +59 -46
- package/src/core/PathTracingSceneGenerator.js +245 -10
- package/src/core/WebGLPathTracer.js +472 -0
- package/src/core/utils/BakedGeometry.js +35 -0
- package/src/core/utils/BufferAttributeUtils.js +64 -0
- package/src/{utils → core/utils}/GeometryPreparationUtils.js +35 -35
- package/src/core/utils/MeshDiff.js +102 -0
- package/src/core/utils/StaticGeometryGenerator.js +285 -0
- package/src/core/utils/convertToStaticGeometry.js +344 -0
- package/src/core/utils/mergeGeometries.js +218 -0
- package/src/core/utils/sceneUpdateUtils.js +96 -0
- package/src/index.d.ts +274 -0
- package/src/index.js +4 -20
- package/src/materials/MaterialBase.js +4 -0
- package/src/materials/fullscreen/ClampedInterpolationMaterial.js +112 -0
- package/src/materials/fullscreen/DenoiseMaterial.js +4 -0
- package/src/materials/pathtracing/PhysicalPathTracingMaterial.js +73 -76
- package/src/materials/pathtracing/glsl/{attenuateHit.glsl.js → attenuate_hit_function.glsl.js} +1 -1
- package/src/materials/pathtracing/glsl/{cameraUtils.glsl.js → camera_util_functions.glsl.js} +1 -1
- package/src/materials/pathtracing/glsl/{directLightContribution.glsl.js → direct_light_contribution_function.glsl.js} +1 -1
- package/src/materials/pathtracing/glsl/{getSurfaceRecord.glsl.js → get_surface_record_function.glsl.js} +1 -1
- package/src/materials/pathtracing/glsl/index.js +6 -0
- package/src/materials/pathtracing/glsl/{renderStructs.glsl.js → render_structs.glsl.js} +1 -1
- package/src/materials/pathtracing/glsl/{traceScene.glsl.js → trace_scene_function.glsl.js} +1 -3
- package/src/materials/surface/AmbientOcclusionMaterial.js +8 -8
- package/src/objects/PhysicalSpotLight.js +2 -2
- package/src/shader/bsdf/{bsdfSampling.glsl.js → bsdf_functions.glsl.js} +19 -72
- package/src/shader/bsdf/{fog.glsl.js → fog_functions.glsl.js} +1 -1
- package/src/shader/bsdf/{ggx.glsl.js → ggx_functions.glsl.js} +1 -1
- package/src/shader/bsdf/index.js +5 -0
- package/src/shader/bsdf/{iridescence.glsl.js → iridescence_functions.glsl.js} +1 -1
- package/src/shader/bsdf/{sheen.glsl.js → sheen_functions.glsl.js} +1 -1
- package/src/shader/bvh/index.js +2 -0
- package/src/shader/{structs/fogMaterialBvh.glsl.js → bvh/inside_fog_volume_function.glsl.js} +1 -1
- package/src/shader/{common/bvhAnyHit.glsl.js → bvh/ray_any_hit_function.glsl.js} +1 -1
- package/src/shader/common/{fresnel.glsl.js → fresnel_functions.glsl.js} +1 -1
- package/src/shader/common/index.js +5 -0
- package/src/shader/common/{math.glsl.js → math_functions.glsl.js} +1 -1
- package/src/shader/common/{intersectShapes.glsl.js → shape_intersection_functions.glsl.js} +1 -1
- package/src/shader/common/{arraySamplerTexelFetch.glsl.js → texture_sample_functions.glsl.js} +1 -1
- package/src/shader/common/{utils.glsl.js → util_functions.glsl.js} +1 -1
- package/src/shader/rand/index.js +3 -0
- package/src/shader/rand/pcg.glsl.js +1 -1
- package/src/shader/rand/sobol.glsl.js +4 -4
- package/src/shader/rand/{stratifiedTexture.glsl.js → stratified.glsl.js} +7 -2
- package/src/shader/sampling/{equirectSampling.glsl.js → equirect_sampling_functions.glsl.js} +1 -2
- package/src/shader/sampling/index.js +3 -0
- package/src/shader/sampling/{lightSampling.glsl.js → light_sampling_functions.glsl.js} +3 -3
- package/src/shader/sampling/{shapeSampling.glsl.js → shape_sampling_functions.glsl.js} +1 -1
- package/src/shader/structs/{cameraStruct.glsl.js → camera_struct.glsl.js} +1 -1
- package/src/shader/structs/{equirectStruct.glsl.js → equirect_struct.glsl.js} +1 -1
- package/src/shader/structs/index.js +5 -0
- package/src/shader/structs/{lightsStruct.glsl.js → lights_struct.glsl.js} +1 -1
- package/src/shader/structs/{materialStruct.glsl.js → material_struct.glsl.js} +2 -2
- package/src/shader/structs/surface_record_struct.glsl.js +63 -0
- package/src/uniforms/EquirectHdrInfoUniform.js +16 -11
- package/src/uniforms/LightsInfoUniformStruct.js +21 -10
- package/src/uniforms/MaterialsTexture.js +27 -86
- package/src/uniforms/RenderTarget2DArray.js +60 -20
- package/src/utils/BlurredEnvMapGenerator.js +12 -5
- package/src/utils/SobolNumberMapGenerator.js +3 -3
- package/src/utils/bufferToHash.js +22 -0
- package/src/core/DynamicPathTracingSceneGenerator.js +0 -164
- package/src/core/MaterialReducer.js +0 -256
- package/src/materials/pathtracing/LambertPathTracingMaterial.js +0 -297
- package/src/uniforms/IESProfilesTexture.js +0 -100
- package/src/uniforms/utils.js +0 -30
- package/src/utils/IESLoader.js +0 -327
- package/src/workers/PathTracingSceneWorker.js +0 -52
|
@@ -105,7 +105,7 @@ function generateSobolSampleFunctions( dim = 1 ) {
|
|
|
105
105
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
export const
|
|
108
|
+
export const sobol_common = /* glsl */`
|
|
109
109
|
|
|
110
110
|
// Utils
|
|
111
111
|
const float SOBOL_FACTOR = 1.0 / 16777216.0;
|
|
@@ -130,7 +130,7 @@ export const sobolCommonGLSL = /* glsl */`
|
|
|
130
130
|
|
|
131
131
|
`;
|
|
132
132
|
|
|
133
|
-
export const
|
|
133
|
+
export const sobol_point_generation = /* glsl */`
|
|
134
134
|
|
|
135
135
|
const uint SOBOL_DIRECTIONS_1[ 32 ] = uint[ 32 ](
|
|
136
136
|
0x80000000u, 0xc0000000u, 0xa0000000u, 0xf0000000u,
|
|
@@ -197,7 +197,7 @@ export const sobolGenerationGLSL = /* glsl */`
|
|
|
197
197
|
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
//
|
|
200
|
+
// NOTE: this sobol "direction" is also available but we can't write out 5 components
|
|
201
201
|
// uint x = index & 0x00ffffffu;
|
|
202
202
|
uint x = sobolReverseBits( getMaskedSobol( index, SOBOL_DIRECTIONS_1 ) ) & 0x00ffffffu;
|
|
203
203
|
uint y = sobolReverseBits( getMaskedSobol( index, SOBOL_DIRECTIONS_2 ) ) & 0x00ffffffu;
|
|
@@ -210,7 +210,7 @@ export const sobolGenerationGLSL = /* glsl */`
|
|
|
210
210
|
|
|
211
211
|
`;
|
|
212
212
|
|
|
213
|
-
export const
|
|
213
|
+
export const sobol_functions = /* glsl */`
|
|
214
214
|
|
|
215
215
|
// Seeds
|
|
216
216
|
uniform sampler2D sobolTexture;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const stratified_functions = /* glsl */`
|
|
2
2
|
|
|
3
3
|
uniform sampler2D stratifiedTexture;
|
|
4
4
|
uniform sampler2D stratifiedOffsetTexture;
|
|
@@ -38,7 +38,12 @@ export const stratifiedTextureGLSL = /* glsl */`
|
|
|
38
38
|
|
|
39
39
|
// tile the small noise texture across the entire screen
|
|
40
40
|
ivec2 noiseSize = ivec2( textureSize( stratifiedOffsetTexture, 0 ) );
|
|
41
|
-
|
|
41
|
+
ivec2 pixel = ivec2( screenCoord.xy ) % noiseSize;
|
|
42
|
+
vec2 pixelWidth = 1.0 / vec2( noiseSize );
|
|
43
|
+
vec2 uv = vec2( pixel ) * pixelWidth + pixelWidth * 0.5;
|
|
44
|
+
|
|
45
|
+
// note that using "texelFetch" here seems to break Android for some reason
|
|
46
|
+
pixelSeed = texture( stratifiedOffsetTexture, uv );
|
|
42
47
|
|
|
43
48
|
}
|
|
44
49
|
|
package/src/shader/sampling/{equirectSampling.glsl.js → equirect_sampling_functions.glsl.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const equirect_functions = /* glsl */`
|
|
2
2
|
|
|
3
3
|
// samples the the given environment map in the given direction
|
|
4
4
|
vec3 sampleEquirectColor( sampler2D envMap, vec3 direction ) {
|
|
@@ -65,5 +65,4 @@ export const equirectSamplingGLSL = /* glsl */`
|
|
|
65
65
|
return float( resolution.x * resolution.y ) * pdf * equirectDirectionPdf( direction );
|
|
66
66
|
|
|
67
67
|
}
|
|
68
|
-
|
|
69
68
|
`;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const light_sampling_functions = /* glsl */`
|
|
2
2
|
|
|
3
3
|
float getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {
|
|
4
4
|
|
|
@@ -26,9 +26,9 @@ export const lightSamplingGLSL = /* glsl */`
|
|
|
26
26
|
float getPhotometricAttenuation( sampler2DArray iesProfiles, int iesProfile, vec3 posToLight, vec3 lightDir, vec3 u, vec3 v ) {
|
|
27
27
|
|
|
28
28
|
float cosTheta = dot( posToLight, lightDir );
|
|
29
|
-
float angle = acos( cosTheta )
|
|
29
|
+
float angle = acos( cosTheta ) / PI;
|
|
30
30
|
|
|
31
|
-
return texture2D( iesProfiles, vec3( 0.0,
|
|
31
|
+
return texture2D( iesProfiles, vec3( angle, 0.0, iesProfile ) ).r;
|
|
32
32
|
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const material_struct = /* glsl */ `
|
|
2
2
|
|
|
3
3
|
struct Material {
|
|
4
4
|
|
|
@@ -176,7 +176,7 @@ export const materialStructGLSL = /* glsl */ `
|
|
|
176
176
|
m.side = s13.a;
|
|
177
177
|
|
|
178
178
|
m.matte = bool( s14.r );
|
|
179
|
-
m.castShadow =
|
|
179
|
+
m.castShadow = bool( s14.g );
|
|
180
180
|
m.vertexColors = bool( int( s14.b ) & 1 );
|
|
181
181
|
m.flatShading = bool( int( s14.b ) & 2 );
|
|
182
182
|
m.fogVolume = bool( int( s14.b ) & 4 );
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export const surface_record_struct = /* glsl */`
|
|
2
|
+
|
|
3
|
+
struct SurfaceRecord {
|
|
4
|
+
|
|
5
|
+
// surface type
|
|
6
|
+
bool volumeParticle;
|
|
7
|
+
|
|
8
|
+
// geometry
|
|
9
|
+
vec3 faceNormal;
|
|
10
|
+
bool frontFace;
|
|
11
|
+
vec3 normal;
|
|
12
|
+
mat3 normalBasis;
|
|
13
|
+
mat3 normalInvBasis;
|
|
14
|
+
|
|
15
|
+
// cached properties
|
|
16
|
+
float eta;
|
|
17
|
+
float f0;
|
|
18
|
+
|
|
19
|
+
// material
|
|
20
|
+
float roughness;
|
|
21
|
+
float filteredRoughness;
|
|
22
|
+
float metalness;
|
|
23
|
+
vec3 color;
|
|
24
|
+
vec3 emission;
|
|
25
|
+
|
|
26
|
+
// transmission
|
|
27
|
+
float ior;
|
|
28
|
+
float transmission;
|
|
29
|
+
bool thinFilm;
|
|
30
|
+
vec3 attenuationColor;
|
|
31
|
+
float attenuationDistance;
|
|
32
|
+
|
|
33
|
+
// clearcoat
|
|
34
|
+
vec3 clearcoatNormal;
|
|
35
|
+
mat3 clearcoatBasis;
|
|
36
|
+
mat3 clearcoatInvBasis;
|
|
37
|
+
float clearcoat;
|
|
38
|
+
float clearcoatRoughness;
|
|
39
|
+
float filteredClearcoatRoughness;
|
|
40
|
+
|
|
41
|
+
// sheen
|
|
42
|
+
float sheen;
|
|
43
|
+
vec3 sheenColor;
|
|
44
|
+
float sheenRoughness;
|
|
45
|
+
|
|
46
|
+
// iridescence
|
|
47
|
+
float iridescence;
|
|
48
|
+
float iridescenceIor;
|
|
49
|
+
float iridescenceThickness;
|
|
50
|
+
|
|
51
|
+
// specular
|
|
52
|
+
vec3 specularColor;
|
|
53
|
+
float specularIntensity;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
struct ScatterRecord {
|
|
57
|
+
float specularPdf;
|
|
58
|
+
float pdf;
|
|
59
|
+
vec3 direction;
|
|
60
|
+
vec3 color;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
`;
|
|
@@ -136,15 +136,15 @@ export class EquirectHdrInfoUniform {
|
|
|
136
136
|
|
|
137
137
|
// Default to a white texture and associated weights so we don't
|
|
138
138
|
// just render black initially.
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
139
|
+
const blackTex = new DataTexture( toHalfFloatArray( new Float32Array( [ 0, 0, 0, 0 ] ) ), 1, 1 );
|
|
140
|
+
blackTex.type = HalfFloatType;
|
|
141
|
+
blackTex.format = RGBAFormat;
|
|
142
|
+
blackTex.minFilter = LinearFilter;
|
|
143
|
+
blackTex.magFilter = LinearFilter;
|
|
144
|
+
blackTex.wrapS = RepeatWrapping;
|
|
145
|
+
blackTex.wrapT = RepeatWrapping;
|
|
146
|
+
blackTex.generateMipmaps = false;
|
|
147
|
+
blackTex.needsUpdate = true;
|
|
148
148
|
|
|
149
149
|
// Stores a map of [0, 1] value -> cumulative importance row & pdf
|
|
150
150
|
// used to sampling a random value to a relevant row to sample from
|
|
@@ -166,10 +166,15 @@ export class EquirectHdrInfoUniform {
|
|
|
166
166
|
conditionalWeights.generateMipmaps = false;
|
|
167
167
|
conditionalWeights.needsUpdate = true;
|
|
168
168
|
|
|
169
|
-
this.map =
|
|
169
|
+
this.map = blackTex;
|
|
170
170
|
this.marginalWeights = marginalWeights;
|
|
171
171
|
this.conditionalWeights = conditionalWeights;
|
|
172
|
-
this.totalSum =
|
|
172
|
+
this.totalSum = 0;
|
|
173
|
+
|
|
174
|
+
// TODO: Add support for float or half float types here. We need to pass this into
|
|
175
|
+
// the preprocess function and ensure our CDF and MDF textures are appropriately sized
|
|
176
|
+
// Ideally we wouldn't upscale a bit depth if we didn't need to.
|
|
177
|
+
// this.type = HalfFloatType;
|
|
173
178
|
|
|
174
179
|
}
|
|
175
180
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DataTexture, RGBAFormat, ClampToEdgeWrapping, FloatType, Vector3, Quaternion, Matrix4, NearestFilter } from 'three';
|
|
2
|
+
import { bufferToHash } from '../utils/bufferToHash.js';
|
|
2
3
|
|
|
3
4
|
const LIGHT_PIXELS = 6;
|
|
4
5
|
const RECT_AREA_LIGHT = 0;
|
|
@@ -6,6 +7,14 @@ const CIRC_AREA_LIGHT = 1;
|
|
|
6
7
|
const SPOT_LIGHT = 2;
|
|
7
8
|
const DIR_LIGHT = 3;
|
|
8
9
|
const POINT_LIGHT = 4;
|
|
10
|
+
|
|
11
|
+
const u = new Vector3();
|
|
12
|
+
const v = new Vector3();
|
|
13
|
+
const m = new Matrix4();
|
|
14
|
+
const worldQuaternion = new Quaternion();
|
|
15
|
+
const eye = new Vector3();
|
|
16
|
+
const target = new Vector3();
|
|
17
|
+
const up = new Vector3( 0, 1, 0 );
|
|
9
18
|
export class LightsInfoUniformStruct {
|
|
10
19
|
|
|
11
20
|
constructor() {
|
|
@@ -42,14 +51,6 @@ export class LightsInfoUniformStruct {
|
|
|
42
51
|
|
|
43
52
|
const floatArray = tex.image.data;
|
|
44
53
|
|
|
45
|
-
const u = new Vector3();
|
|
46
|
-
const v = new Vector3();
|
|
47
|
-
const m = new Matrix4();
|
|
48
|
-
const worldQuaternion = new Quaternion();
|
|
49
|
-
const eye = new Vector3();
|
|
50
|
-
const target = new Vector3();
|
|
51
|
-
const up = new Vector3( 0, 1, 0 );
|
|
52
|
-
|
|
53
54
|
for ( let i = 0, l = lights.length; i < l; i ++ ) {
|
|
54
55
|
|
|
55
56
|
const l = lights[ i ];
|
|
@@ -172,7 +173,7 @@ export class LightsInfoUniformStruct {
|
|
|
172
173
|
floatArray[ baseIndex + ( index ++ ) ] = Math.cos( l.angle * ( 1 - l.penumbra ) );
|
|
173
174
|
|
|
174
175
|
// iesProfile
|
|
175
|
-
floatArray[ baseIndex + ( index ++ ) ] = l.
|
|
176
|
+
floatArray[ baseIndex + ( index ++ ) ] = l.iesMap ? iesTextures.indexOf( l.iesMap ) : - 1;
|
|
176
177
|
|
|
177
178
|
} else if ( l.isPointLight ) {
|
|
178
179
|
|
|
@@ -210,9 +211,19 @@ export class LightsInfoUniformStruct {
|
|
|
210
211
|
|
|
211
212
|
}
|
|
212
213
|
|
|
213
|
-
tex.needsUpdate = true;
|
|
214
214
|
this.count = lights.length;
|
|
215
215
|
|
|
216
|
+
const hash = bufferToHash( floatArray.buffer );
|
|
217
|
+
if ( this.hash !== hash ) {
|
|
218
|
+
|
|
219
|
+
this.hash = hash;
|
|
220
|
+
tex.needsUpdate = true;
|
|
221
|
+
return true;
|
|
222
|
+
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return false;
|
|
226
|
+
|
|
216
227
|
}
|
|
217
228
|
|
|
218
229
|
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { DataTexture, RGBAFormat, ClampToEdgeWrapping, FloatType, FrontSide, BackSide, DoubleSide, NearestFilter } from 'three';
|
|
2
|
-
import {
|
|
2
|
+
import { getTextureHash } from '../core/utils/sceneUpdateUtils.js';
|
|
3
|
+
import { bufferToHash } from '../utils/bufferToHash.js';
|
|
3
4
|
|
|
4
5
|
const MATERIAL_PIXELS = 45;
|
|
5
6
|
const MATERIAL_STRIDE = MATERIAL_PIXELS * 4;
|
|
6
7
|
|
|
7
|
-
const MATTE_OFFSET = 14 * 4 + 0; // s14.r
|
|
8
|
-
const SHADOW_OFFSET = 14 * 4 + 1; // s14.g
|
|
9
|
-
|
|
10
8
|
class MaterialFeatures {
|
|
11
9
|
|
|
12
10
|
constructor() {
|
|
@@ -56,44 +54,10 @@ export class MaterialsTexture extends DataTexture {
|
|
|
56
54
|
this.minFilter = NearestFilter;
|
|
57
55
|
this.magFilter = NearestFilter;
|
|
58
56
|
this.generateMipmaps = false;
|
|
59
|
-
this.threeCompatibilityTransforms = false;
|
|
60
57
|
this.features = new MaterialFeatures();
|
|
61
58
|
|
|
62
59
|
}
|
|
63
60
|
|
|
64
|
-
setCastShadow( materialIndex, cast ) {
|
|
65
|
-
|
|
66
|
-
// invert the shadow value so we default to "true" when initializing a material
|
|
67
|
-
const array = this.image.data;
|
|
68
|
-
const index = materialIndex * MATERIAL_STRIDE + SHADOW_OFFSET;
|
|
69
|
-
array[ index ] = ! cast ? 1 : 0;
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
getCastShadow( materialIndex ) {
|
|
74
|
-
|
|
75
|
-
const array = this.image.data;
|
|
76
|
-
const index = materialIndex * MATERIAL_STRIDE + SHADOW_OFFSET;
|
|
77
|
-
return ! Boolean( array[ index ] );
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
setMatte( materialIndex, matte ) {
|
|
82
|
-
|
|
83
|
-
const array = this.image.data;
|
|
84
|
-
const index = materialIndex * MATERIAL_STRIDE + MATTE_OFFSET;
|
|
85
|
-
array[ index ] = matte ? 1 : 0;
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
getMatte( materialIndex ) {
|
|
90
|
-
|
|
91
|
-
const array = this.image.data;
|
|
92
|
-
const index = materialIndex * MATERIAL_STRIDE + MATTE_OFFSET;
|
|
93
|
-
return Boolean( array[ index ] );
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
61
|
updateFrom( materials, textures ) {
|
|
98
62
|
|
|
99
63
|
function getTexture( material, key, def = - 1 ) {
|
|
@@ -101,7 +65,7 @@ export class MaterialsTexture extends DataTexture {
|
|
|
101
65
|
if ( key in material && material[ key ] ) {
|
|
102
66
|
|
|
103
67
|
const hash = getTextureHash( material[ key ] );
|
|
104
|
-
return
|
|
68
|
+
return textureLookUp[ hash ];
|
|
105
69
|
|
|
106
70
|
} else {
|
|
107
71
|
|
|
@@ -117,50 +81,18 @@ export class MaterialsTexture extends DataTexture {
|
|
|
117
81
|
|
|
118
82
|
}
|
|
119
83
|
|
|
120
|
-
function getUVTransformTexture( material ) {
|
|
121
|
-
|
|
122
|
-
// https://github.com/mrdoob/three.js/blob/f3a832e637c98a404c64dae8174625958455e038/src/renderers/webgl/WebGLMaterials.js#L204-L306
|
|
123
|
-
// https://threejs.org/docs/#api/en/textures/Texture.offset
|
|
124
|
-
// fallback order of textures to use as a common uv transform
|
|
125
|
-
return material.map ||
|
|
126
|
-
material.specularMap ||
|
|
127
|
-
material.displacementMap ||
|
|
128
|
-
material.normalMap ||
|
|
129
|
-
material.bumpMap ||
|
|
130
|
-
material.roughnessMap ||
|
|
131
|
-
material.metalnessMap ||
|
|
132
|
-
material.alphaMap ||
|
|
133
|
-
material.emissiveMap ||
|
|
134
|
-
material.clearcoatMap ||
|
|
135
|
-
material.clearcoatNormalMap ||
|
|
136
|
-
material.clearcoatRoughnessMap ||
|
|
137
|
-
material.iridescenceMap ||
|
|
138
|
-
material.iridescenceThicknessMap ||
|
|
139
|
-
material.specularIntensityMap ||
|
|
140
|
-
material.specularColorMap ||
|
|
141
|
-
material.transmissionMap ||
|
|
142
|
-
material.thicknessMap ||
|
|
143
|
-
material.sheenColorMap ||
|
|
144
|
-
material.sheenRoughnessMap ||
|
|
145
|
-
null;
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
|
|
149
84
|
function writeTextureMatrixToArray( material, textureKey, array, offset ) {
|
|
150
85
|
|
|
151
|
-
|
|
152
|
-
if ( threeCompatibilityTransforms ) {
|
|
86
|
+
const texture = material[ textureKey ] && material[ textureKey ].isTexture ? material[ textureKey ] : null;
|
|
153
87
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
} else {
|
|
88
|
+
// check if texture exists
|
|
89
|
+
if ( texture ) {
|
|
157
90
|
|
|
158
|
-
|
|
91
|
+
if ( texture.matrixAutoUpdate ) {
|
|
159
92
|
|
|
160
|
-
|
|
93
|
+
texture.updateMatrix();
|
|
161
94
|
|
|
162
|
-
|
|
163
|
-
if ( texture ) {
|
|
95
|
+
}
|
|
164
96
|
|
|
165
97
|
const elements = texture.matrix.elements;
|
|
166
98
|
|
|
@@ -187,14 +119,13 @@ export class MaterialsTexture extends DataTexture {
|
|
|
187
119
|
let index = 0;
|
|
188
120
|
const pixelCount = materials.length * MATERIAL_PIXELS;
|
|
189
121
|
const dimension = Math.ceil( Math.sqrt( pixelCount ) ) || 1;
|
|
190
|
-
const {
|
|
122
|
+
const { image, features } = this;
|
|
191
123
|
|
|
192
|
-
//
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
for ( let i = 0, l = uniqueTextures.length; i < l; i ++ ) {
|
|
124
|
+
// index the list of textures based on shareable source
|
|
125
|
+
const textureLookUp = {};
|
|
126
|
+
for ( let i = 0, l = textures.length; i < l; i ++ ) {
|
|
196
127
|
|
|
197
|
-
|
|
128
|
+
textureLookUp[ getTextureHash( textures[ i ] ) ] = i;
|
|
198
129
|
|
|
199
130
|
}
|
|
200
131
|
|
|
@@ -446,8 +377,8 @@ export class MaterialsTexture extends DataTexture {
|
|
|
446
377
|
}
|
|
447
378
|
|
|
448
379
|
// sample 14
|
|
449
|
-
index
|
|
450
|
-
index
|
|
380
|
+
floatArray[ index ++ ] = Number( getField( m, 'matte', false ) ); // matte
|
|
381
|
+
floatArray[ index ++ ] = Number( getField( m, 'castShadow', true ) ); // shadow
|
|
451
382
|
floatArray[ index ++ ] = Number( m.vertexColors ) | ( Number( m.flatShading ) << 1 ); // vertexColors & flatShading
|
|
452
383
|
floatArray[ index ++ ] = Number( m.transparent ); // transparent
|
|
453
384
|
|
|
@@ -498,7 +429,17 @@ export class MaterialsTexture extends DataTexture {
|
|
|
498
429
|
|
|
499
430
|
}
|
|
500
431
|
|
|
501
|
-
|
|
432
|
+
// check if the contents have changed
|
|
433
|
+
const hash = bufferToHash( floatArray.buffer );
|
|
434
|
+
if ( this.hash !== hash ) {
|
|
435
|
+
|
|
436
|
+
this.hash = hash;
|
|
437
|
+
this.needsUpdate = true;
|
|
438
|
+
return true;
|
|
439
|
+
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
return false;
|
|
502
443
|
|
|
503
444
|
}
|
|
504
445
|
|