@shapediver/viewer.rendering-engine.rendering-engine-threejs 3.15.0 → 3.15.2
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/dist/loaders/MaterialLoader.d.ts +1 -1
- package/dist/utils/MaterialInstancer.d.ts +33 -0
- package/dist/utils/MaterialInstancer.d.ts.map +1 -0
- package/dist/utils/MaterialInstancer.js +179 -0
- package/dist/utils/MaterialInstancer.js.map +1 -0
- package/dist/utils/PerformanceMonitor.d.ts +67 -0
- package/dist/utils/PerformanceMonitor.d.ts.map +1 -0
- package/dist/utils/PerformanceMonitor.js +286 -0
- package/dist/utils/PerformanceMonitor.js.map +1 -0
- package/package.json +17 -17
|
@@ -71,7 +71,7 @@ export declare class MaterialLoader implements ILoader {
|
|
|
71
71
|
assignEnvironmentMapRotation(value: quat): void;
|
|
72
72
|
assignPointSize(p: number): void;
|
|
73
73
|
cacheSize(): number;
|
|
74
|
-
createMaterial(type: GEOMETRY_MATERIAL_TYPE, incomingData: IMaterialAbstractData | GeometryData, materialData: IMaterialAbstractData | null, materialSettings?: MaterialSettings): THREE.Material |
|
|
74
|
+
createMaterial(type: GEOMETRY_MATERIAL_TYPE, incomingData: IMaterialAbstractData | GeometryData, materialData: IMaterialAbstractData | null, materialSettings?: MaterialSettings): THREE.Material | THREE.LineBasicMaterial | THREE.MeshBasicMaterial | THREE.PointsMaterial | MultiPointsMaterial;
|
|
75
75
|
emptyMaterialCache(): void;
|
|
76
76
|
getMaterialProperties(materialData: IMaterialAbstractData | null, type: GEOMETRY_MATERIAL_TYPE, materialSettings?: MaterialSettings): {
|
|
77
77
|
properties: ThreeJsMaterialParameterTypes;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as THREE from "three";
|
|
2
|
+
/**
|
|
3
|
+
* Utility for creating instanced meshes with per-instance material properties
|
|
4
|
+
* This allows thousands of objects with different materials to be rendered in a single draw call
|
|
5
|
+
*/
|
|
6
|
+
export declare class MaterialInstancer {
|
|
7
|
+
/**
|
|
8
|
+
* Convert multiple meshes with different materials into a single instanced mesh
|
|
9
|
+
* with per-instance material attributes
|
|
10
|
+
*
|
|
11
|
+
* @param meshes Array of meshes to convert (must share same base geometry)
|
|
12
|
+
* @param baseGeometry The shared geometry
|
|
13
|
+
* @returns InstancedMesh with per-instance material properties
|
|
14
|
+
*/
|
|
15
|
+
static createInstancedMeshWithMaterialAttributes(meshes: THREE.Mesh[], baseGeometry: THREE.BufferGeometry): THREE.InstancedMesh;
|
|
16
|
+
/**
|
|
17
|
+
* Group meshes by similar geometry and create instanced meshes for each group
|
|
18
|
+
*
|
|
19
|
+
* @param meshes Array of all meshes
|
|
20
|
+
* @returns Array of instanced meshes (one per unique geometry)
|
|
21
|
+
*/
|
|
22
|
+
static groupAndInstanceByGeometry(meshes: THREE.Mesh[]): THREE.InstancedMesh[];
|
|
23
|
+
/**
|
|
24
|
+
* Analyze how many draw calls could be saved by instancing
|
|
25
|
+
*/
|
|
26
|
+
static analyzeInstancingPotential(meshes: THREE.Mesh[]): {
|
|
27
|
+
totalMeshes: number;
|
|
28
|
+
uniqueGeometries: number;
|
|
29
|
+
potentialDrawCallReduction: number;
|
|
30
|
+
groupSizes: Map<string, number>;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=MaterialInstancer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MaterialInstancer.d.ts","sourceRoot":"","sources":["../../src/utils/MaterialInstancer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;;GAGG;AACH,qBAAa,iBAAiB;IAC7B;;;;;;;OAOG;WACW,yCAAyC,CACtD,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,EACpB,YAAY,EAAE,KAAK,CAAC,cAAc,GAChC,KAAK,CAAC,aAAa;IAuItB;;;;;OAKG;WACW,0BAA0B,CACvC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,GAClB,KAAK,CAAC,aAAa,EAAE;IAgCxB;;OAEG;WACW,0BAA0B,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG;QAC/D,WAAW,EAAE,MAAM,CAAC;QACpB,gBAAgB,EAAE,MAAM,CAAC;QACzB,0BAA0B,EAAE,MAAM,CAAC;QACnC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAChC;CAmBD"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.MaterialInstancer = void 0;
|
|
27
|
+
const THREE = __importStar(require("three"));
|
|
28
|
+
/**
|
|
29
|
+
* Utility for creating instanced meshes with per-instance material properties
|
|
30
|
+
* This allows thousands of objects with different materials to be rendered in a single draw call
|
|
31
|
+
*/
|
|
32
|
+
class MaterialInstancer {
|
|
33
|
+
/**
|
|
34
|
+
* Convert multiple meshes with different materials into a single instanced mesh
|
|
35
|
+
* with per-instance material attributes
|
|
36
|
+
*
|
|
37
|
+
* @param meshes Array of meshes to convert (must share same base geometry)
|
|
38
|
+
* @param baseGeometry The shared geometry
|
|
39
|
+
* @returns InstancedMesh with per-instance material properties
|
|
40
|
+
*/
|
|
41
|
+
static createInstancedMeshWithMaterialAttributes(meshes, baseGeometry) {
|
|
42
|
+
var _a, _b, _c;
|
|
43
|
+
const count = meshes.length;
|
|
44
|
+
// Create a material that supports per-instance properties
|
|
45
|
+
const material = new THREE.MeshStandardMaterial();
|
|
46
|
+
// Modify the shader to use per-instance attributes
|
|
47
|
+
material.onBeforeCompile = (shader) => {
|
|
48
|
+
// Add instance attributes to vertex shader
|
|
49
|
+
shader.vertexShader = shader.vertexShader.replace('#include <common>', `
|
|
50
|
+
#include <common>
|
|
51
|
+
attribute vec3 instanceColor;
|
|
52
|
+
attribute float instanceMetalness;
|
|
53
|
+
attribute float instanceRoughness;
|
|
54
|
+
attribute float instanceOpacity;
|
|
55
|
+
varying vec3 vInstanceColor;
|
|
56
|
+
varying float vInstanceMetalness;
|
|
57
|
+
varying float vInstanceRoughness;
|
|
58
|
+
varying float vInstanceOpacity;
|
|
59
|
+
`);
|
|
60
|
+
shader.vertexShader = shader.vertexShader.replace('#include <begin_vertex>', `
|
|
61
|
+
#include <begin_vertex>
|
|
62
|
+
vInstanceColor = instanceColor;
|
|
63
|
+
vInstanceMetalness = instanceMetalness;
|
|
64
|
+
vInstanceRoughness = instanceRoughness;
|
|
65
|
+
vInstanceOpacity = instanceOpacity;
|
|
66
|
+
`);
|
|
67
|
+
// Use instance attributes in fragment shader
|
|
68
|
+
shader.fragmentShader = shader.fragmentShader.replace('#include <common>', `
|
|
69
|
+
#include <common>
|
|
70
|
+
varying vec3 vInstanceColor;
|
|
71
|
+
varying float vInstanceMetalness;
|
|
72
|
+
varying float vInstanceRoughness;
|
|
73
|
+
varying float vInstanceOpacity;
|
|
74
|
+
`);
|
|
75
|
+
shader.fragmentShader = shader.fragmentShader.replace('#include <color_fragment>', `
|
|
76
|
+
#include <color_fragment>
|
|
77
|
+
diffuseColor.rgb = vInstanceColor;
|
|
78
|
+
`);
|
|
79
|
+
shader.fragmentShader = shader.fragmentShader.replace('#include <roughnessmap_fragment>', `
|
|
80
|
+
float roughnessFactor = vInstanceRoughness;
|
|
81
|
+
#ifdef USE_ROUGHNESSMAP
|
|
82
|
+
vec4 texelRoughness = texture2D( roughnessMap, vRoughnessMapUv );
|
|
83
|
+
roughnessFactor *= texelRoughness.g;
|
|
84
|
+
#endif
|
|
85
|
+
`);
|
|
86
|
+
shader.fragmentShader = shader.fragmentShader.replace('#include <metalnessmap_fragment>', `
|
|
87
|
+
float metalnessFactor = vInstanceMetalness;
|
|
88
|
+
#ifdef USE_METALNESSMAP
|
|
89
|
+
vec4 texelMetalness = texture2D( metalnessMap, vMetalnessMapUv );
|
|
90
|
+
metalnessFactor *= texelMetalness.b;
|
|
91
|
+
#endif
|
|
92
|
+
`);
|
|
93
|
+
};
|
|
94
|
+
const instancedMesh = new THREE.InstancedMesh(baseGeometry, material, count);
|
|
95
|
+
// Create per-instance attribute buffers
|
|
96
|
+
const colors = new Float32Array(count * 3);
|
|
97
|
+
const metalness = new Float32Array(count);
|
|
98
|
+
const roughness = new Float32Array(count);
|
|
99
|
+
const opacity = new Float32Array(count);
|
|
100
|
+
const matrix = new THREE.Matrix4();
|
|
101
|
+
const color = new THREE.Color();
|
|
102
|
+
// Extract properties from each mesh
|
|
103
|
+
for (let i = 0; i < count; i++) {
|
|
104
|
+
const mesh = meshes[i];
|
|
105
|
+
const mat = mesh.material;
|
|
106
|
+
// Set transform
|
|
107
|
+
mesh.updateMatrixWorld();
|
|
108
|
+
instancedMesh.setMatrixAt(i, mesh.matrixWorld);
|
|
109
|
+
// Extract material properties
|
|
110
|
+
if (mat.color) {
|
|
111
|
+
color.copy(mat.color);
|
|
112
|
+
colors[i * 3] = color.r;
|
|
113
|
+
colors[i * 3 + 1] = color.g;
|
|
114
|
+
colors[i * 3 + 2] = color.b;
|
|
115
|
+
}
|
|
116
|
+
metalness[i] = (_a = mat.metalness) !== null && _a !== void 0 ? _a : 0;
|
|
117
|
+
roughness[i] = (_b = mat.roughness) !== null && _b !== void 0 ? _b : 1;
|
|
118
|
+
opacity[i] = (_c = mat.opacity) !== null && _c !== void 0 ? _c : 1;
|
|
119
|
+
}
|
|
120
|
+
// Add instance attributes to geometry
|
|
121
|
+
baseGeometry.setAttribute('instanceColor', new THREE.InstancedBufferAttribute(colors, 3));
|
|
122
|
+
baseGeometry.setAttribute('instanceMetalness', new THREE.InstancedBufferAttribute(metalness, 1));
|
|
123
|
+
baseGeometry.setAttribute('instanceRoughness', new THREE.InstancedBufferAttribute(roughness, 1));
|
|
124
|
+
baseGeometry.setAttribute('instanceOpacity', new THREE.InstancedBufferAttribute(opacity, 1));
|
|
125
|
+
instancedMesh.instanceMatrix.needsUpdate = true;
|
|
126
|
+
instancedMesh.frustumCulled = false;
|
|
127
|
+
return instancedMesh;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Group meshes by similar geometry and create instanced meshes for each group
|
|
131
|
+
*
|
|
132
|
+
* @param meshes Array of all meshes
|
|
133
|
+
* @returns Array of instanced meshes (one per unique geometry)
|
|
134
|
+
*/
|
|
135
|
+
static groupAndInstanceByGeometry(meshes) {
|
|
136
|
+
// Group by geometry
|
|
137
|
+
const geometryGroups = new Map();
|
|
138
|
+
for (const mesh of meshes) {
|
|
139
|
+
const geomId = mesh.geometry.uuid;
|
|
140
|
+
if (!geometryGroups.has(geomId)) {
|
|
141
|
+
geometryGroups.set(geomId, []);
|
|
142
|
+
}
|
|
143
|
+
geometryGroups.get(geomId).push(mesh);
|
|
144
|
+
}
|
|
145
|
+
const instancedMeshes = [];
|
|
146
|
+
// Create instanced mesh for each geometry group
|
|
147
|
+
for (const [geomId, groupMeshes] of geometryGroups) {
|
|
148
|
+
if (groupMeshes.length === 1) {
|
|
149
|
+
// Keep single meshes as is
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const baseGeometry = groupMeshes[0].geometry;
|
|
153
|
+
const instancedMesh = this.createInstancedMeshWithMaterialAttributes(groupMeshes, baseGeometry);
|
|
154
|
+
instancedMeshes.push(instancedMesh);
|
|
155
|
+
}
|
|
156
|
+
return instancedMeshes;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Analyze how many draw calls could be saved by instancing
|
|
160
|
+
*/
|
|
161
|
+
static analyzeInstancingPotential(meshes) {
|
|
162
|
+
const geometryGroups = new Map();
|
|
163
|
+
for (const mesh of meshes) {
|
|
164
|
+
const geomId = mesh.geometry.uuid;
|
|
165
|
+
geometryGroups.set(geomId, (geometryGroups.get(geomId) || 0) + 1);
|
|
166
|
+
}
|
|
167
|
+
const totalMeshes = meshes.length;
|
|
168
|
+
const uniqueGeometries = geometryGroups.size;
|
|
169
|
+
const potentialDrawCallReduction = totalMeshes - uniqueGeometries;
|
|
170
|
+
return {
|
|
171
|
+
totalMeshes,
|
|
172
|
+
uniqueGeometries,
|
|
173
|
+
potentialDrawCallReduction,
|
|
174
|
+
groupSizes: geometryGroups
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
exports.MaterialInstancer = MaterialInstancer;
|
|
179
|
+
//# sourceMappingURL=MaterialInstancer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MaterialInstancer.js","sourceRoot":"","sources":["../../src/utils/MaterialInstancer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as THREE from "three";
|
|
2
|
+
/**
|
|
3
|
+
* Performance monitoring and optimization recommendations
|
|
4
|
+
*/
|
|
5
|
+
export declare class PerformanceMonitor {
|
|
6
|
+
private frameCount;
|
|
7
|
+
private lastTime;
|
|
8
|
+
private fps;
|
|
9
|
+
private drawCalls;
|
|
10
|
+
private triangles;
|
|
11
|
+
private programs;
|
|
12
|
+
private triangleAccumulator;
|
|
13
|
+
private drawCallAccumulator;
|
|
14
|
+
private sampleCount;
|
|
15
|
+
/**
|
|
16
|
+
* Update performance metrics (call once per frame)
|
|
17
|
+
*/
|
|
18
|
+
update(renderer: THREE.WebGLRenderer, currentTime: number): void;
|
|
19
|
+
/**
|
|
20
|
+
* Get current performance metrics
|
|
21
|
+
*/
|
|
22
|
+
getMetrics(): {
|
|
23
|
+
fps: number;
|
|
24
|
+
drawCalls: number;
|
|
25
|
+
triangles: number;
|
|
26
|
+
programs: number;
|
|
27
|
+
msPerFrame: number;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Get optimization recommendations based on current metrics
|
|
31
|
+
*/
|
|
32
|
+
getRecommendations(): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Analyze scene and provide detailed optimization report
|
|
35
|
+
*/
|
|
36
|
+
static analyzeScene(scene: THREE.Scene): {
|
|
37
|
+
totalObjects: number;
|
|
38
|
+
meshes: number;
|
|
39
|
+
instancedMeshes: number;
|
|
40
|
+
skinnedMeshes: number;
|
|
41
|
+
lights: number;
|
|
42
|
+
materials: Set<THREE.Material>;
|
|
43
|
+
uniqueMaterials: number;
|
|
44
|
+
geometries: Set<THREE.BufferGeometry>;
|
|
45
|
+
uniqueGeometries: number;
|
|
46
|
+
totalVertices: number;
|
|
47
|
+
totalTriangles: number;
|
|
48
|
+
smallMeshes: number;
|
|
49
|
+
mediumMeshes: number;
|
|
50
|
+
largeMeshes: number;
|
|
51
|
+
potentialInstancingCandidates: number;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Generate detailed performance report
|
|
55
|
+
*/
|
|
56
|
+
static generateReport(scene: THREE.Scene, renderer: THREE.WebGLRenderer, currentMetrics: {
|
|
57
|
+
fps: number;
|
|
58
|
+
drawCalls: number;
|
|
59
|
+
triangles: number;
|
|
60
|
+
programs: number;
|
|
61
|
+
}): string;
|
|
62
|
+
/**
|
|
63
|
+
* Log performance metrics to console with color coding
|
|
64
|
+
*/
|
|
65
|
+
logMetrics(): void;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=PerformanceMonitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PerformanceMonitor.d.ts","sourceRoot":"","sources":["../../src/utils/PerformanceMonitor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;GAEG;AACH,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,WAAW,CAAK;IAExB;;OAEG;IACI,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,aAAa,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAoCvE;;OAEG;IACI,UAAU,IAAI;QACpB,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;KACnB;IAUD;;OAEG;IACI,kBAAkB,IAAI,MAAM,EAAE;IAqDrC;;OAEG;WACW,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG;QAC/C,YAAY,EAAE,MAAM,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE,MAAM,CAAC;QACxB,aAAa,EAAE,MAAM,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC/B,eAAe,EAAE,MAAM,CAAC;QACxB,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACtC,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,6BAA6B,EAAE,MAAM,CAAC;KACtC;IAmGD;;OAEG;WACW,cAAc,CAC3B,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,QAAQ,EAAE,KAAK,CAAC,aAAa,EAC7B,cAAc,EAAE;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;KACjB,GACC,MAAM;IA4DT;;OAEG;IACI,UAAU,IAAI,IAAI;CAwBzB"}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.PerformanceMonitor = void 0;
|
|
27
|
+
const THREE = __importStar(require("three"));
|
|
28
|
+
/**
|
|
29
|
+
* Performance monitoring and optimization recommendations
|
|
30
|
+
*/
|
|
31
|
+
class PerformanceMonitor {
|
|
32
|
+
constructor() {
|
|
33
|
+
this.frameCount = 0;
|
|
34
|
+
this.lastTime = 0;
|
|
35
|
+
this.fps = 0;
|
|
36
|
+
this.drawCalls = 0;
|
|
37
|
+
this.triangles = 0;
|
|
38
|
+
this.programs = 0;
|
|
39
|
+
this.triangleAccumulator = 0;
|
|
40
|
+
this.drawCallAccumulator = 0;
|
|
41
|
+
this.sampleCount = 0;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Update performance metrics (call once per frame)
|
|
45
|
+
*/
|
|
46
|
+
update(renderer, currentTime) {
|
|
47
|
+
var _a;
|
|
48
|
+
this.frameCount++;
|
|
49
|
+
// Accumulate render info values
|
|
50
|
+
const currentDrawCalls = renderer.info.render.calls;
|
|
51
|
+
const currentTriangles = renderer.info.render.triangles;
|
|
52
|
+
if (currentDrawCalls > 0) {
|
|
53
|
+
this.drawCallAccumulator += currentDrawCalls;
|
|
54
|
+
this.triangleAccumulator += currentTriangles;
|
|
55
|
+
this.sampleCount++;
|
|
56
|
+
}
|
|
57
|
+
// Update FPS and averaged values every second
|
|
58
|
+
if (currentTime - this.lastTime >= 1000) {
|
|
59
|
+
this.fps = this.frameCount;
|
|
60
|
+
this.frameCount = 0;
|
|
61
|
+
// Calculate averages
|
|
62
|
+
if (this.sampleCount > 0) {
|
|
63
|
+
this.drawCalls = Math.round(this.drawCallAccumulator / this.sampleCount);
|
|
64
|
+
this.triangles = Math.round(this.triangleAccumulator / this.sampleCount);
|
|
65
|
+
}
|
|
66
|
+
// Reset accumulators
|
|
67
|
+
this.drawCallAccumulator = 0;
|
|
68
|
+
this.triangleAccumulator = 0;
|
|
69
|
+
this.sampleCount = 0;
|
|
70
|
+
this.lastTime = currentTime;
|
|
71
|
+
}
|
|
72
|
+
// Always update programs count
|
|
73
|
+
this.programs = ((_a = renderer.info.programs) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get current performance metrics
|
|
77
|
+
*/
|
|
78
|
+
getMetrics() {
|
|
79
|
+
return {
|
|
80
|
+
fps: this.fps,
|
|
81
|
+
drawCalls: this.drawCalls,
|
|
82
|
+
triangles: this.triangles,
|
|
83
|
+
programs: this.programs,
|
|
84
|
+
msPerFrame: this.fps > 0 ? 1000 / this.fps : 0,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get optimization recommendations based on current metrics
|
|
89
|
+
*/
|
|
90
|
+
getRecommendations() {
|
|
91
|
+
const recommendations = [];
|
|
92
|
+
const metrics = this.getMetrics();
|
|
93
|
+
// Draw call optimization
|
|
94
|
+
if (metrics.drawCalls > 1000) {
|
|
95
|
+
recommendations.push(`⚠️ HIGH DRAW CALLS (${metrics.drawCalls}): Consider using GPU instancing or geometry batching to reduce draw calls below 1000`);
|
|
96
|
+
}
|
|
97
|
+
else if (metrics.drawCalls > 500) {
|
|
98
|
+
recommendations.push(`⚡ MODERATE DRAW CALLS (${metrics.drawCalls}): Consider batching geometries with the same material`);
|
|
99
|
+
}
|
|
100
|
+
// Triangle count
|
|
101
|
+
if (metrics.triangles > 5000000) {
|
|
102
|
+
recommendations.push(`⚠️ HIGH TRIANGLE COUNT (${(metrics.triangles / 1000000).toFixed(1)}M): Consider using LOD (Level of Detail) or reduce mesh complexity`);
|
|
103
|
+
}
|
|
104
|
+
// Shader programs
|
|
105
|
+
if (metrics.programs > 50) {
|
|
106
|
+
recommendations.push(`⚠️ MANY SHADER PROGRAMS (${metrics.programs}): Share materials where possible to reduce shader compilation and switching overhead`);
|
|
107
|
+
}
|
|
108
|
+
// FPS
|
|
109
|
+
if (metrics.fps < 30) {
|
|
110
|
+
recommendations.push(`🔴 LOW FPS (${metrics.fps}): Critical performance issue detected. Primary bottleneck is likely ${metrics.drawCalls > 1000
|
|
111
|
+
? "draw calls"
|
|
112
|
+
: metrics.triangles > 5000000
|
|
113
|
+
? "triangle count"
|
|
114
|
+
: "shader complexity or fill rate"}`);
|
|
115
|
+
}
|
|
116
|
+
else if (metrics.fps < 55) {
|
|
117
|
+
recommendations.push(`🟡 MODERATE FPS (${metrics.fps}): Performance could be improved`);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
recommendations.push(`✅ GOOD FPS (${metrics.fps}): Performance is acceptable`);
|
|
121
|
+
}
|
|
122
|
+
return recommendations;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Analyze scene and provide detailed optimization report
|
|
126
|
+
*/
|
|
127
|
+
static analyzeScene(scene) {
|
|
128
|
+
let totalObjects = 0;
|
|
129
|
+
let meshes = 0;
|
|
130
|
+
let instancedMeshes = 0;
|
|
131
|
+
let skinnedMeshes = 0;
|
|
132
|
+
let lights = 0;
|
|
133
|
+
let totalVertices = 0;
|
|
134
|
+
let totalTriangles = 0;
|
|
135
|
+
let smallMeshes = 0;
|
|
136
|
+
let mediumMeshes = 0;
|
|
137
|
+
let largeMeshes = 0;
|
|
138
|
+
const materials = new Set();
|
|
139
|
+
const geometries = new Set();
|
|
140
|
+
const geometrySignatures = new Map(); // For instancing detection
|
|
141
|
+
scene.traverse((obj) => {
|
|
142
|
+
var _a, _b;
|
|
143
|
+
totalObjects++;
|
|
144
|
+
if (obj instanceof THREE.Mesh) {
|
|
145
|
+
meshes++;
|
|
146
|
+
if (obj instanceof THREE.InstancedMesh) {
|
|
147
|
+
instancedMeshes++;
|
|
148
|
+
}
|
|
149
|
+
else if (obj instanceof THREE.SkinnedMesh) {
|
|
150
|
+
skinnedMeshes++;
|
|
151
|
+
}
|
|
152
|
+
// Collect materials
|
|
153
|
+
if (Array.isArray(obj.material)) {
|
|
154
|
+
obj.material.forEach((m) => materials.add(m));
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
materials.add(obj.material);
|
|
158
|
+
}
|
|
159
|
+
// Collect geometries
|
|
160
|
+
geometries.add(obj.geometry);
|
|
161
|
+
// Count vertices and triangles
|
|
162
|
+
const vertexCount = ((_a = obj.geometry.attributes.position) === null || _a === void 0 ? void 0 : _a.count) || 0;
|
|
163
|
+
totalVertices += vertexCount;
|
|
164
|
+
const indexCount = ((_b = obj.geometry.index) === null || _b === void 0 ? void 0 : _b.count) || vertexCount;
|
|
165
|
+
totalTriangles += indexCount / 3;
|
|
166
|
+
// Categorize mesh size
|
|
167
|
+
if (vertexCount < 100) {
|
|
168
|
+
smallMeshes++;
|
|
169
|
+
}
|
|
170
|
+
else if (vertexCount < 10000) {
|
|
171
|
+
mediumMeshes++;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
largeMeshes++;
|
|
175
|
+
}
|
|
176
|
+
// Detect potential instancing candidates
|
|
177
|
+
// Create a signature based on geometry and material
|
|
178
|
+
const geomId = obj.geometry.uuid;
|
|
179
|
+
const matId = Array.isArray(obj.material)
|
|
180
|
+
? obj.material.map((m) => m.uuid).join(",")
|
|
181
|
+
: obj.material.uuid;
|
|
182
|
+
const signature = `${geomId}_${matId}`;
|
|
183
|
+
geometrySignatures.set(signature, (geometrySignatures.get(signature) || 0) + 1);
|
|
184
|
+
}
|
|
185
|
+
else if (obj instanceof THREE.Light) {
|
|
186
|
+
lights++;
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
// Count instancing candidates (geometries used multiple times)
|
|
190
|
+
let potentialInstancingCandidates = 0;
|
|
191
|
+
for (const count of geometrySignatures.values()) {
|
|
192
|
+
if (count > 1) {
|
|
193
|
+
potentialInstancingCandidates += count;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
totalObjects,
|
|
198
|
+
meshes,
|
|
199
|
+
instancedMeshes,
|
|
200
|
+
skinnedMeshes,
|
|
201
|
+
lights,
|
|
202
|
+
materials,
|
|
203
|
+
uniqueMaterials: materials.size,
|
|
204
|
+
geometries,
|
|
205
|
+
uniqueGeometries: geometries.size,
|
|
206
|
+
totalVertices,
|
|
207
|
+
totalTriangles,
|
|
208
|
+
smallMeshes,
|
|
209
|
+
mediumMeshes,
|
|
210
|
+
largeMeshes,
|
|
211
|
+
potentialInstancingCandidates,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Generate detailed performance report
|
|
216
|
+
*/
|
|
217
|
+
static generateReport(scene, renderer, currentMetrics) {
|
|
218
|
+
const analysis = this.analyzeScene(scene);
|
|
219
|
+
let report = "═══════════════════════════════════════\n";
|
|
220
|
+
report += " PERFORMANCE ANALYSIS REPORT\n";
|
|
221
|
+
report += "═══════════════════════════════════════\n\n";
|
|
222
|
+
report += "📊 CURRENT METRICS:\n";
|
|
223
|
+
report += ` FPS: ${currentMetrics.fps}\n`;
|
|
224
|
+
report += ` Draw Calls: ${currentMetrics.drawCalls}\n`;
|
|
225
|
+
report += ` Triangles: ${(currentMetrics.triangles / 1000).toFixed(1)}K\n`;
|
|
226
|
+
report += ` Shader Programs: ${currentMetrics.programs}\n\n`;
|
|
227
|
+
report += "🔍 SCENE ANALYSIS:\n";
|
|
228
|
+
report += ` Total Objects: ${analysis.totalObjects}\n`;
|
|
229
|
+
report += ` Meshes: ${analysis.meshes}\n`;
|
|
230
|
+
report += ` ├─ Instanced: ${analysis.instancedMeshes}\n`;
|
|
231
|
+
report += ` ├─ Skinned: ${analysis.skinnedMeshes}\n`;
|
|
232
|
+
report += ` └─ Regular: ${analysis.meshes - analysis.instancedMeshes - analysis.skinnedMeshes}\n`;
|
|
233
|
+
report += ` Lights: ${analysis.lights}\n`;
|
|
234
|
+
report += ` Unique Materials: ${analysis.uniqueMaterials}\n`;
|
|
235
|
+
report += ` Unique Geometries: ${analysis.uniqueGeometries}\n`;
|
|
236
|
+
report += ` Total Vertices: ${(analysis.totalVertices / 1000).toFixed(1)}K\n\n`;
|
|
237
|
+
report += "📦 MESH SIZE DISTRIBUTION:\n";
|
|
238
|
+
report += ` Small (< 100 verts): ${analysis.smallMeshes}\n`;
|
|
239
|
+
report += ` Medium (100-10K verts): ${analysis.mediumMeshes}\n`;
|
|
240
|
+
report += ` Large (> 10K verts): ${analysis.largeMeshes}\n\n`;
|
|
241
|
+
report += "💡 OPTIMIZATION OPPORTUNITIES:\n";
|
|
242
|
+
if (analysis.smallMeshes > 100) {
|
|
243
|
+
report += ` ⚠️ ${analysis.smallMeshes} small meshes detected!\n`;
|
|
244
|
+
report += ` → Consider batching or using instancing\n`;
|
|
245
|
+
report += ` → Potential draw call reduction: ${analysis.smallMeshes - Math.ceil(analysis.smallMeshes / analysis.uniqueMaterials)}\n\n`;
|
|
246
|
+
}
|
|
247
|
+
if (analysis.potentialInstancingCandidates > 0) {
|
|
248
|
+
report += ` ⚡ ${analysis.potentialInstancingCandidates} meshes could use instancing\n`;
|
|
249
|
+
report += ` → These meshes share geometry and material\n`;
|
|
250
|
+
report += ` → Convert to InstancedMesh for massive performance gain\n\n`;
|
|
251
|
+
}
|
|
252
|
+
if (analysis.uniqueMaterials > 50) {
|
|
253
|
+
report += ` ⚠️ ${analysis.uniqueMaterials} unique materials\n`;
|
|
254
|
+
report += ` → Try to share materials where possible\n`;
|
|
255
|
+
report += ` → Each material = potential shader program = state change\n\n`;
|
|
256
|
+
}
|
|
257
|
+
const geometryReuse = analysis.meshes / analysis.uniqueGeometries;
|
|
258
|
+
if (geometryReuse < 2) {
|
|
259
|
+
report += ` ℹ️ Low geometry reuse (${geometryReuse.toFixed(1)}x)\n`;
|
|
260
|
+
report += ` → Consider reusing geometries across multiple objects\n\n`;
|
|
261
|
+
}
|
|
262
|
+
report += "═══════════════════════════════════════\n";
|
|
263
|
+
return report;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Log performance metrics to console with color coding
|
|
267
|
+
*/
|
|
268
|
+
logMetrics() {
|
|
269
|
+
const metrics = this.getMetrics();
|
|
270
|
+
console.group("🎯 Performance Metrics");
|
|
271
|
+
console.log(`%cFPS: ${metrics.fps}`, `color: ${metrics.fps >= 55 ? "green" : metrics.fps >= 30 ? "orange" : "red"}`);
|
|
272
|
+
console.log(`%cDraw Calls: ${metrics.drawCalls}`, `color: ${metrics.drawCalls <= 500 ? "green" : metrics.drawCalls <= 1000 ? "orange" : "red"}`);
|
|
273
|
+
console.log(`Triangles: ${(metrics.triangles / 1000).toFixed(1)}K`);
|
|
274
|
+
console.log(`Shader Programs: ${metrics.programs}`);
|
|
275
|
+
console.log(`Frame Time: ${metrics.msPerFrame.toFixed(2)}ms`);
|
|
276
|
+
console.groupEnd();
|
|
277
|
+
const recommendations = this.getRecommendations();
|
|
278
|
+
if (recommendations.length > 0) {
|
|
279
|
+
console.group("💡 Recommendations");
|
|
280
|
+
recommendations.forEach((rec) => console.log(rec));
|
|
281
|
+
console.groupEnd();
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
exports.PerformanceMonitor = PerformanceMonitor;
|
|
286
|
+
//# sourceMappingURL=PerformanceMonitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PerformanceMonitor.js","sourceRoot":"","sources":["../../src/utils/PerformanceMonitor.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapediver/viewer.rendering-engine.rendering-engine-threejs",
|
|
3
|
-
"version": "3.15.
|
|
3
|
+
"version": "3.15.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "Michael Oppitz <michael@shapediver.com>",
|
|
@@ -38,21 +38,21 @@
|
|
|
38
38
|
"testEnvironment": "node"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@shapediver/viewer.data-engine.gltf-converter": "3.15.
|
|
42
|
-
"@shapediver/viewer.data-engine.shared-types": "3.15.
|
|
43
|
-
"@shapediver/viewer.data-engine.tag3d-engine": "3.15.
|
|
44
|
-
"@shapediver/viewer.rendering-engine.animation-engine": "3.15.
|
|
45
|
-
"@shapediver/viewer.rendering-engine.animation-frame-engine": "3.15.
|
|
46
|
-
"@shapediver/viewer.rendering-engine.camera-engine": "3.15.
|
|
47
|
-
"@shapediver/viewer.rendering-engine.canvas-engine": "3.15.
|
|
48
|
-
"@shapediver/viewer.rendering-engine.intersection-engine": "3.15.
|
|
49
|
-
"@shapediver/viewer.rendering-engine.light-engine": "3.15.
|
|
50
|
-
"@shapediver/viewer.rendering-engine.rendering-engine": "3.15.
|
|
51
|
-
"@shapediver/viewer.shared.global-access-objects": "3.15.
|
|
52
|
-
"@shapediver/viewer.shared.math": "3.15.
|
|
53
|
-
"@shapediver/viewer.shared.node-tree": "3.15.
|
|
54
|
-
"@shapediver/viewer.shared.services": "3.15.
|
|
55
|
-
"@shapediver/viewer.shared.types": "3.15.
|
|
41
|
+
"@shapediver/viewer.data-engine.gltf-converter": "3.15.2",
|
|
42
|
+
"@shapediver/viewer.data-engine.shared-types": "3.15.2",
|
|
43
|
+
"@shapediver/viewer.data-engine.tag3d-engine": "3.15.2",
|
|
44
|
+
"@shapediver/viewer.rendering-engine.animation-engine": "3.15.2",
|
|
45
|
+
"@shapediver/viewer.rendering-engine.animation-frame-engine": "3.15.2",
|
|
46
|
+
"@shapediver/viewer.rendering-engine.camera-engine": "3.15.2",
|
|
47
|
+
"@shapediver/viewer.rendering-engine.canvas-engine": "3.15.2",
|
|
48
|
+
"@shapediver/viewer.rendering-engine.intersection-engine": "3.15.2",
|
|
49
|
+
"@shapediver/viewer.rendering-engine.light-engine": "3.15.2",
|
|
50
|
+
"@shapediver/viewer.rendering-engine.rendering-engine": "3.15.2",
|
|
51
|
+
"@shapediver/viewer.shared.global-access-objects": "3.15.2",
|
|
52
|
+
"@shapediver/viewer.shared.math": "3.15.2",
|
|
53
|
+
"@shapediver/viewer.shared.node-tree": "3.15.2",
|
|
54
|
+
"@shapediver/viewer.shared.services": "3.15.2",
|
|
55
|
+
"@shapediver/viewer.shared.types": "3.15.2",
|
|
56
56
|
"@tweenjs/tween.js": "^18.6.4",
|
|
57
57
|
"@types/stats.js": "^0.17.0",
|
|
58
58
|
"@types/three": "0.162.0",
|
|
@@ -61,5 +61,5 @@
|
|
|
61
61
|
"stats.js": "^0.17.0",
|
|
62
62
|
"three": "0.162.0"
|
|
63
63
|
},
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "b0fafd0073307a1fb4b8d5824f8554d733427131"
|
|
65
65
|
}
|