three-gpu-pathtracer 0.0.1 → 0.0.4
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 +678 -386
- package/build/index.module.js +3166 -1690
- package/build/index.module.js.map +1 -1
- package/build/index.umd.cjs +3176 -1692
- package/build/index.umd.cjs.map +1 -1
- package/package.json +60 -57
- package/src/core/DynamicPathTracingSceneGenerator.js +106 -0
- package/src/core/MaterialReducer.js +256 -256
- package/src/core/PathTracingRenderer.js +125 -28
- package/src/core/PathTracingSceneGenerator.js +52 -46
- package/src/core/PhysicalCamera.js +28 -0
- package/src/index.js +25 -21
- package/src/materials/AlphaDisplayMaterial.js +48 -0
- package/src/materials/AmbientOcclusionMaterial.js +197 -197
- package/src/materials/BlendMaterial.js +67 -0
- package/src/materials/LambertPathTracingMaterial.js +285 -285
- package/src/materials/MaterialBase.js +56 -56
- package/src/materials/PhysicalPathTracingMaterial.js +684 -370
- package/src/shader/shaderEnvMapSampling.js +67 -0
- package/src/shader/shaderGGXFunctions.js +108 -107
- package/src/shader/shaderMaterialSampling.js +345 -333
- package/src/shader/shaderStructs.js +131 -30
- package/src/shader/shaderUtils.js +246 -140
- package/src/uniforms/EquirectHdrInfoUniform.js +263 -0
- package/src/uniforms/MaterialsTexture.js +251 -0
- package/src/uniforms/PhysicalCameraUniform.js +36 -0
- package/src/uniforms/RenderTarget2DArray.js +93 -80
- package/src/utils/BlurredEnvMapGenerator.js +113 -0
- package/src/utils/GeometryPreparationUtils.js +194 -172
- package/src/utils/UVUnwrapper.js +101 -101
- package/src/workers/PathTracingSceneWorker.js +40 -0
- package/src/uniforms/EquirectPdfUniform.js +0 -132
- package/src/uniforms/MaterialStructArrayUniform.js +0 -18
- package/src/uniforms/MaterialStructUniform.js +0 -94
- package/src/viewers/PathTracingViewer.js +0 -259
package/src/utils/UVUnwrapper.js
CHANGED
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
// https://github.com/mozilla/Spoke/commit/9701d647020e09d584885bd457eb225e9995c12f
|
|
2
|
-
import XAtlas from 'xatlas-web';
|
|
3
|
-
import { BufferGeometry, Float32BufferAttribute, Uint32BufferAttribute } from 'three';
|
|
4
|
-
|
|
5
|
-
export class UVUnwrapper {
|
|
6
|
-
|
|
7
|
-
constructor() {
|
|
8
|
-
|
|
9
|
-
this._module = null;
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
async load() {
|
|
14
|
-
|
|
15
|
-
const wasmurl = new URL( '../../node_modules/xatlas-web/dist/xatlas-web.wasm', import.meta.url );
|
|
16
|
-
this._module = XAtlas( {
|
|
17
|
-
|
|
18
|
-
locateFile( path ) {
|
|
19
|
-
|
|
20
|
-
if ( path.endsWith( '.wasm' ) ) {
|
|
21
|
-
|
|
22
|
-
return wasmurl.toString();
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return path;
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
} );
|
|
31
|
-
return this._module.ready;
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
generate( geometry ) {
|
|
36
|
-
|
|
37
|
-
const xatlas = this._module;
|
|
38
|
-
const originalVertexCount = geometry.attributes.position.count;
|
|
39
|
-
const originalIndexCount = geometry.index.count;
|
|
40
|
-
|
|
41
|
-
xatlas.createAtlas();
|
|
42
|
-
|
|
43
|
-
const meshInfo = xatlas.createMesh( originalVertexCount, originalIndexCount, true, true );
|
|
44
|
-
xatlas.HEAPU16.set( geometry.index.array, meshInfo.indexOffset / Uint16Array.BYTES_PER_ELEMENT );
|
|
45
|
-
xatlas.HEAPF32.set( geometry.attributes.position.array, meshInfo.positionOffset / Float32Array.BYTES_PER_ELEMENT );
|
|
46
|
-
xatlas.HEAPF32.set( geometry.attributes.normal.array, meshInfo.normalOffset / Float32Array.BYTES_PER_ELEMENT );
|
|
47
|
-
xatlas.HEAPF32.set( geometry.attributes.uv.array, meshInfo.uvOffset / Float32Array.BYTES_PER_ELEMENT );
|
|
48
|
-
|
|
49
|
-
const statusCode = xatlas.addMesh();
|
|
50
|
-
if ( statusCode !== AddMeshStatus.Success ) {
|
|
51
|
-
|
|
52
|
-
throw new Error( `UVUnwrapper: Error adding mesh. Status code ${ statusCode }` );
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
xatlas.generateAtlas();
|
|
57
|
-
|
|
58
|
-
const meshData = xatlas.getMeshData( meshInfo.meshId );
|
|
59
|
-
const oldPositionArray = geometry.attributes.position.array;
|
|
60
|
-
const oldNormalArray = geometry.attributes.normal.array;
|
|
61
|
-
const oldUvArray = geometry.attributes.uv.array;
|
|
62
|
-
|
|
63
|
-
const newPositionArray = new Float32Array( meshData.newVertexCount * 3 );
|
|
64
|
-
const newNormalArray = new Float32Array( meshData.newVertexCount * 3 );
|
|
65
|
-
const newUvArray = new Float32Array( meshData.newVertexCount * 2 );
|
|
66
|
-
const newUv2Array = new Float32Array( xatlas.HEAPF32.buffer, meshData.uvOffset, meshData.newVertexCount * 2 );
|
|
67
|
-
const newIndexArray = new Uint32Array( xatlas.HEAPU32.buffer, meshData.indexOffset, meshData.newIndexCount );
|
|
68
|
-
const originalIndexArray = new Uint32Array(
|
|
69
|
-
xatlas.HEAPU32.buffer,
|
|
70
|
-
meshData.originalIndexOffset,
|
|
71
|
-
meshData.newVertexCount
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
for ( let i = 0; i < meshData.newVertexCount; i ++ ) {
|
|
75
|
-
|
|
76
|
-
const originalIndex = originalIndexArray[ i ];
|
|
77
|
-
newPositionArray[ i * 3 ] = oldPositionArray[ originalIndex * 3 ];
|
|
78
|
-
newPositionArray[ i * 3 + 1 ] = oldPositionArray[ originalIndex * 3 + 1 ];
|
|
79
|
-
newPositionArray[ i * 3 + 2 ] = oldPositionArray[ originalIndex * 3 + 2 ];
|
|
80
|
-
newNormalArray[ i * 3 ] = oldNormalArray[ originalIndex * 3 ];
|
|
81
|
-
newNormalArray[ i * 3 + 1 ] = oldNormalArray[ originalIndex * 3 + 1 ];
|
|
82
|
-
newNormalArray[ i * 3 + 2 ] = oldNormalArray[ originalIndex * 3 + 2 ];
|
|
83
|
-
newUvArray[ i * 2 ] = oldUvArray[ originalIndex * 2 ];
|
|
84
|
-
newUvArray[ i * 2 + 1 ] = oldUvArray[ originalIndex * 2 + 1 ];
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const newGeometry = new BufferGeometry();
|
|
89
|
-
newGeometry.addAttribute( 'position', new Float32BufferAttribute( newPositionArray, 3 ) );
|
|
90
|
-
newGeometry.addAttribute( 'normal', new Float32BufferAttribute( newNormalArray, 3 ) );
|
|
91
|
-
newGeometry.addAttribute( 'uv', new Float32BufferAttribute( newUvArray, 2 ) );
|
|
92
|
-
newGeometry.addAttribute( 'uv2', new Float32BufferAttribute( newUv2Array, 2 ) );
|
|
93
|
-
newGeometry.setIndex( new Uint32BufferAttribute( newIndexArray, 1 ) );
|
|
94
|
-
|
|
95
|
-
mesh.geometry = newGeometry;
|
|
96
|
-
|
|
97
|
-
xatlas.destroyAtlas();
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
}
|
|
1
|
+
// https://github.com/mozilla/Spoke/commit/9701d647020e09d584885bd457eb225e9995c12f
|
|
2
|
+
import XAtlas from 'xatlas-web';
|
|
3
|
+
import { BufferGeometry, Float32BufferAttribute, Uint32BufferAttribute } from 'three';
|
|
4
|
+
|
|
5
|
+
export class UVUnwrapper {
|
|
6
|
+
|
|
7
|
+
constructor() {
|
|
8
|
+
|
|
9
|
+
this._module = null;
|
|
10
|
+
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async load() {
|
|
14
|
+
|
|
15
|
+
const wasmurl = new URL( '../../node_modules/xatlas-web/dist/xatlas-web.wasm', import.meta.url );
|
|
16
|
+
this._module = XAtlas( {
|
|
17
|
+
|
|
18
|
+
locateFile( path ) {
|
|
19
|
+
|
|
20
|
+
if ( path.endsWith( '.wasm' ) ) {
|
|
21
|
+
|
|
22
|
+
return wasmurl.toString();
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return path;
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
} );
|
|
31
|
+
return this._module.ready;
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
generate( geometry ) {
|
|
36
|
+
|
|
37
|
+
const xatlas = this._module;
|
|
38
|
+
const originalVertexCount = geometry.attributes.position.count;
|
|
39
|
+
const originalIndexCount = geometry.index.count;
|
|
40
|
+
|
|
41
|
+
xatlas.createAtlas();
|
|
42
|
+
|
|
43
|
+
const meshInfo = xatlas.createMesh( originalVertexCount, originalIndexCount, true, true );
|
|
44
|
+
xatlas.HEAPU16.set( geometry.index.array, meshInfo.indexOffset / Uint16Array.BYTES_PER_ELEMENT );
|
|
45
|
+
xatlas.HEAPF32.set( geometry.attributes.position.array, meshInfo.positionOffset / Float32Array.BYTES_PER_ELEMENT );
|
|
46
|
+
xatlas.HEAPF32.set( geometry.attributes.normal.array, meshInfo.normalOffset / Float32Array.BYTES_PER_ELEMENT );
|
|
47
|
+
xatlas.HEAPF32.set( geometry.attributes.uv.array, meshInfo.uvOffset / Float32Array.BYTES_PER_ELEMENT );
|
|
48
|
+
|
|
49
|
+
const statusCode = xatlas.addMesh();
|
|
50
|
+
if ( statusCode !== AddMeshStatus.Success ) {
|
|
51
|
+
|
|
52
|
+
throw new Error( `UVUnwrapper: Error adding mesh. Status code ${ statusCode }` );
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
xatlas.generateAtlas();
|
|
57
|
+
|
|
58
|
+
const meshData = xatlas.getMeshData( meshInfo.meshId );
|
|
59
|
+
const oldPositionArray = geometry.attributes.position.array;
|
|
60
|
+
const oldNormalArray = geometry.attributes.normal.array;
|
|
61
|
+
const oldUvArray = geometry.attributes.uv.array;
|
|
62
|
+
|
|
63
|
+
const newPositionArray = new Float32Array( meshData.newVertexCount * 3 );
|
|
64
|
+
const newNormalArray = new Float32Array( meshData.newVertexCount * 3 );
|
|
65
|
+
const newUvArray = new Float32Array( meshData.newVertexCount * 2 );
|
|
66
|
+
const newUv2Array = new Float32Array( xatlas.HEAPF32.buffer, meshData.uvOffset, meshData.newVertexCount * 2 );
|
|
67
|
+
const newIndexArray = new Uint32Array( xatlas.HEAPU32.buffer, meshData.indexOffset, meshData.newIndexCount );
|
|
68
|
+
const originalIndexArray = new Uint32Array(
|
|
69
|
+
xatlas.HEAPU32.buffer,
|
|
70
|
+
meshData.originalIndexOffset,
|
|
71
|
+
meshData.newVertexCount
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
for ( let i = 0; i < meshData.newVertexCount; i ++ ) {
|
|
75
|
+
|
|
76
|
+
const originalIndex = originalIndexArray[ i ];
|
|
77
|
+
newPositionArray[ i * 3 ] = oldPositionArray[ originalIndex * 3 ];
|
|
78
|
+
newPositionArray[ i * 3 + 1 ] = oldPositionArray[ originalIndex * 3 + 1 ];
|
|
79
|
+
newPositionArray[ i * 3 + 2 ] = oldPositionArray[ originalIndex * 3 + 2 ];
|
|
80
|
+
newNormalArray[ i * 3 ] = oldNormalArray[ originalIndex * 3 ];
|
|
81
|
+
newNormalArray[ i * 3 + 1 ] = oldNormalArray[ originalIndex * 3 + 1 ];
|
|
82
|
+
newNormalArray[ i * 3 + 2 ] = oldNormalArray[ originalIndex * 3 + 2 ];
|
|
83
|
+
newUvArray[ i * 2 ] = oldUvArray[ originalIndex * 2 ];
|
|
84
|
+
newUvArray[ i * 2 + 1 ] = oldUvArray[ originalIndex * 2 + 1 ];
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const newGeometry = new BufferGeometry();
|
|
89
|
+
newGeometry.addAttribute( 'position', new Float32BufferAttribute( newPositionArray, 3 ) );
|
|
90
|
+
newGeometry.addAttribute( 'normal', new Float32BufferAttribute( newNormalArray, 3 ) );
|
|
91
|
+
newGeometry.addAttribute( 'uv', new Float32BufferAttribute( newUvArray, 2 ) );
|
|
92
|
+
newGeometry.addAttribute( 'uv2', new Float32BufferAttribute( newUv2Array, 2 ) );
|
|
93
|
+
newGeometry.setIndex( new Uint32BufferAttribute( newIndexArray, 1 ) );
|
|
94
|
+
|
|
95
|
+
mesh.geometry = newGeometry;
|
|
96
|
+
|
|
97
|
+
xatlas.destroyAtlas();
|
|
98
|
+
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { PathTracingSceneGenerator } from '../core/PathTracingSceneGenerator.js';
|
|
2
|
+
import { SAH } from 'three-mesh-bvh';
|
|
3
|
+
import { GenerateMeshBVHWorker } from 'three-mesh-bvh/src/workers/GenerateMeshBVHWorker.js';
|
|
4
|
+
|
|
5
|
+
export class PathTracingSceneWorker extends PathTracingSceneGenerator {
|
|
6
|
+
|
|
7
|
+
constructor() {
|
|
8
|
+
|
|
9
|
+
super();
|
|
10
|
+
this.bvhGenerator = new GenerateMeshBVHWorker();
|
|
11
|
+
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
generate( scene, options = {} ) {
|
|
15
|
+
|
|
16
|
+
const { bvhGenerator } = this;
|
|
17
|
+
const { geometry, materials, textures } = this.prepScene( scene );
|
|
18
|
+
|
|
19
|
+
const bvhOptions = { strategy: SAH, ...options, maxLeafTris: 1 };
|
|
20
|
+
const bvhPromise = bvhGenerator.generate( geometry, bvhOptions );
|
|
21
|
+
return bvhPromise.then( bvh => {
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
scene,
|
|
25
|
+
materials,
|
|
26
|
+
textures,
|
|
27
|
+
bvh,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
} );
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
dispose() {
|
|
35
|
+
|
|
36
|
+
this.bvhGenerator.dispose();
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
}
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { Color, DataTexture, FloatType, RGFormat, LinearFilter } from 'three';
|
|
2
|
-
|
|
3
|
-
function RGBEToLinear( r, g, b, e, target ) {
|
|
4
|
-
|
|
5
|
-
const exp = e * 255.0 - 128.0;
|
|
6
|
-
target.set( r, g, b ).multiplyScalar( Math.pow( exp ) );
|
|
7
|
-
return target;
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export class EquirectPdfUniform {
|
|
12
|
-
|
|
13
|
-
constructor() {
|
|
14
|
-
|
|
15
|
-
const marginalData = new DataTexture();
|
|
16
|
-
marginalData.type = FloatType;
|
|
17
|
-
marginalData.format = RGFormat;
|
|
18
|
-
marginalData.minFilter = LinearFilter;
|
|
19
|
-
marginalData.maxFilter = LinearFilter;
|
|
20
|
-
marginalData.generateMipmaps = false;
|
|
21
|
-
|
|
22
|
-
const conditionalData = new DataTexture();
|
|
23
|
-
conditionalData.type = FloatType;
|
|
24
|
-
conditionalData.format = RGFormat;
|
|
25
|
-
conditionalData.minFilter = LinearFilter;
|
|
26
|
-
conditionalData.maxFilter = LinearFilter;
|
|
27
|
-
conditionalData.generateMipmaps = false;
|
|
28
|
-
|
|
29
|
-
this.marginalData = marginalData;
|
|
30
|
-
this.conditionalData = conditionalData;
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
updateFrom( hdr ) {
|
|
35
|
-
|
|
36
|
-
// TODO: another reference implementation with a different approach:
|
|
37
|
-
// https://github.com/nvpro-samples/vk_mini_samples/blob/main/hdr_sampling/src/hdr_env.cpp#L243
|
|
38
|
-
|
|
39
|
-
// https://github.com/knightcrawler25/GLSL-PathTracer/blob/master/src/loaders/hdrloader.cpp
|
|
40
|
-
const { width, height, data } = hdr.image;
|
|
41
|
-
const color = new Color();
|
|
42
|
-
const hsl = {};
|
|
43
|
-
|
|
44
|
-
// track the importance of any given pixel in the image by tracking its weight relative to other pixels in the image
|
|
45
|
-
const pdfConditional = new Float32Array( width * height );
|
|
46
|
-
const cdfConditional = new Float32Array( width * height );
|
|
47
|
-
|
|
48
|
-
const pdfMarginal = new Float32Array( height );
|
|
49
|
-
const cdfMarginal = new Float32Array( height );
|
|
50
|
-
|
|
51
|
-
let cumulativeWeightMarginal = 0.0;
|
|
52
|
-
for ( let y = 0; y < height; y ++ ) {
|
|
53
|
-
|
|
54
|
-
let cumulativeWeight = 0.0;
|
|
55
|
-
for ( let x = 0; x < width; x ++ ) {
|
|
56
|
-
|
|
57
|
-
const i = y * width + x;
|
|
58
|
-
const r = data[ 4 * i + 0 ];
|
|
59
|
-
const g = data[ 4 * i + 1 ];
|
|
60
|
-
const b = data[ 4 * i + 2 ];
|
|
61
|
-
const e = data[ 4 * i + 3 ];
|
|
62
|
-
|
|
63
|
-
// the probability of the pixel being selected in this row is the
|
|
64
|
-
// scale of the luminance relative to the rest of the pixels.
|
|
65
|
-
// TODO: this should also account for the solid angle of the pixel when sampling
|
|
66
|
-
const weight = RGBEToLinear( r, g, b, e, color ).getHSL( hsl ).l;
|
|
67
|
-
cumulativeWeight += weight;
|
|
68
|
-
|
|
69
|
-
pdfConditional[ i ] = weight;
|
|
70
|
-
cdfConditional[ i ] = cumulativeWeight;
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// scale the pdf and cdf to [0.0, 1.0]
|
|
75
|
-
for ( let i = 0, l = pdfConditional.length; i < l; i ++ ) {
|
|
76
|
-
|
|
77
|
-
pdfConditional[ i ] /= cumulativeWeight;
|
|
78
|
-
cdfConditional[ i ] /= cumulativeWeight;
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
cumulativeWeightMarginal += cumulativeWeight;
|
|
83
|
-
|
|
84
|
-
// compute the marginal pdf and cdf along the height of the map.
|
|
85
|
-
pdfMarginal[ y ] = cumulativeWeight;
|
|
86
|
-
cdfMarginal[ y ] = cumulativeWeightMarginal;
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// scale the marginal pdf and cdf to [0.0, 1.0]
|
|
91
|
-
for ( let i = 0, l = pdfMarginal.length; i < l; i ++ ) {
|
|
92
|
-
|
|
93
|
-
pdfMarginal[ i ] /= cumulativeWeightMarginal;
|
|
94
|
-
cdfMarginal[ i ] /= cumulativeWeightMarginal;
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// compute a sorted index of distributions and the probabilities along them for both
|
|
99
|
-
// the marginal and conditional data. These will be used to sample with a random number
|
|
100
|
-
// to retrieve a uv value to sample in the environment map.
|
|
101
|
-
const marginalDataArray = new Float32Array( height * 2 );
|
|
102
|
-
const conditionalDataArray = new Float32Array( width * height * 2 );
|
|
103
|
-
|
|
104
|
-
for ( let i = 0; i < height; i ++ ) {
|
|
105
|
-
|
|
106
|
-
//const dist = ( i + 1 ) / height;
|
|
107
|
-
const row = 0; // TODO: find the row that lies at the given cumulative distribution value above
|
|
108
|
-
marginalDataArray[ 2 * i + 0 ] = row / height;
|
|
109
|
-
marginalDataArray[ 2 * i + 1 ] = pdfMarginal[ i ];
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
for ( let y = 0; y < height; y ++ ) {
|
|
114
|
-
|
|
115
|
-
for ( let x = 0; x < width; x ++ ) {
|
|
116
|
-
|
|
117
|
-
const i = y * width + x;
|
|
118
|
-
//const dist = ( x + 1 ) / width;
|
|
119
|
-
const col = 0; // TODO: find the column in the given row that lies at the cumulative dist value above
|
|
120
|
-
conditionalDataArray[ 2 * i + 0 ] = col / width;
|
|
121
|
-
conditionalDataArray[ 2 * i + 1 ] = pdfConditional[ i ];
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
this.marginalData.image = { width, height, data: marginalDataArray };
|
|
128
|
-
this.conditionalData.image = { width, height, data: conditionalDataArray };
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { MaterialStructUniform } from './MaterialStructUniform.js';
|
|
2
|
-
|
|
3
|
-
export class MaterialStructArrayUniform extends Array {
|
|
4
|
-
|
|
5
|
-
updateFrom( materials, textures ) {
|
|
6
|
-
|
|
7
|
-
while ( this.length > materials.length ) this.pop();
|
|
8
|
-
while ( this.length < materials.length ) this.push( new MaterialStructUniform() );
|
|
9
|
-
|
|
10
|
-
for ( let i = 0, l = this.length; i < l; i ++ ) {
|
|
11
|
-
|
|
12
|
-
this[ i ].updateFrom( materials[ i ], textures );
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { Color, Vector2 } from 'three';
|
|
2
|
-
export class MaterialStructUniform {
|
|
3
|
-
|
|
4
|
-
constructor() {
|
|
5
|
-
|
|
6
|
-
this.init();
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
init() {
|
|
11
|
-
|
|
12
|
-
this.color = new Color( 0xffffff );
|
|
13
|
-
this.map = - 1;
|
|
14
|
-
|
|
15
|
-
this.metalness = 1.0;
|
|
16
|
-
this.metalnessMap = - 1;
|
|
17
|
-
|
|
18
|
-
this.roughness = 1.0;
|
|
19
|
-
this.roughnessMap = - 1;
|
|
20
|
-
|
|
21
|
-
this.ior = 1.0;
|
|
22
|
-
this.transmission = 0.0;
|
|
23
|
-
this.transmissionMap = - 1;
|
|
24
|
-
|
|
25
|
-
this.emissive = new Color( 0 );
|
|
26
|
-
this.emissiveIntensity = 1.0;
|
|
27
|
-
this.emissiveMap = - 1;
|
|
28
|
-
|
|
29
|
-
this.normalMap = - 1;
|
|
30
|
-
this.normalScale = new Vector2( 1, 1 );
|
|
31
|
-
|
|
32
|
-
this.opacity = 1.0;
|
|
33
|
-
this.alphaTest = 0.0;
|
|
34
|
-
|
|
35
|
-
// TODO: Clearcoat
|
|
36
|
-
|
|
37
|
-
// TODO: Sheen
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
updateFrom( material, textures = [] ) {
|
|
42
|
-
|
|
43
|
-
this.init();
|
|
44
|
-
|
|
45
|
-
// color
|
|
46
|
-
if ( 'color' in material ) this.color.copy( material.color );
|
|
47
|
-
else material.color.set( 0xffffff );
|
|
48
|
-
|
|
49
|
-
this.map = textures.indexOf( material.map );
|
|
50
|
-
|
|
51
|
-
// metalness
|
|
52
|
-
if ( 'metalness' in material ) this.metalness = material.metalness;
|
|
53
|
-
else this.metalness = 1.0;
|
|
54
|
-
|
|
55
|
-
this.metalnessMap = textures.indexOf( material.metalnessMap );
|
|
56
|
-
|
|
57
|
-
// roughness
|
|
58
|
-
if ( 'roughness' in material ) this.roughness = material.roughness;
|
|
59
|
-
else this.roughness = 1.0;
|
|
60
|
-
|
|
61
|
-
this.roughnessMap = textures.indexOf( material.roughnessMap );
|
|
62
|
-
|
|
63
|
-
// transmission
|
|
64
|
-
if ( 'ior' in material ) this.ior = material.ior;
|
|
65
|
-
else this.ior = 1.0;
|
|
66
|
-
|
|
67
|
-
if ( 'transmission' in material ) this.transmission = material.transmission;
|
|
68
|
-
else this.transmission = 0.0;
|
|
69
|
-
|
|
70
|
-
if ( 'transmissionMap' in material ) this.transmissionMap = textures.indexOf( material.transmissionMap );
|
|
71
|
-
|
|
72
|
-
// emission
|
|
73
|
-
if ( 'emissive' in material ) this.emissive.copy( material.emissive );
|
|
74
|
-
else this.emissive.set( 0 );
|
|
75
|
-
|
|
76
|
-
if ( 'emissiveIntensity' in material ) this.emissiveIntensity = material.emissiveIntensity;
|
|
77
|
-
else this.emissiveIntensity = 1.0;
|
|
78
|
-
|
|
79
|
-
this.emissiveMap = textures.indexOf( material.emissiveMap );
|
|
80
|
-
|
|
81
|
-
// normals
|
|
82
|
-
this.normalMap = textures.indexOf( material.normalMap );
|
|
83
|
-
if ( 'normalScale' in material ) this.normalScale.copy( material.normalScale );
|
|
84
|
-
else this.normalScale.set( 1, 1 );
|
|
85
|
-
|
|
86
|
-
// opacity
|
|
87
|
-
this.opacity = material.opacity;
|
|
88
|
-
|
|
89
|
-
// alpha test
|
|
90
|
-
this.alphaTest = material.alphaTest;
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
}
|