@nice2dev/ui-3d 1.3.14 → 1.3.16

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.
Files changed (108) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/collaborative/collaborativeScene.js +160 -206
  3. package/dist/cjs/core/editorAsk.js +51 -41
  4. package/dist/cjs/core/i18n.js +13 -14
  5. package/dist/cjs/core/threeCompat.js +29 -42
  6. package/dist/cjs/dance/DanceBridge.js +148 -177
  7. package/dist/cjs/dance/DanceScoreEngine.js +209 -221
  8. package/dist/cjs/dance/PoseDetector.js +302 -275
  9. package/dist/cjs/index.js +110 -113
  10. package/dist/cjs/material/MaterialEditor.module.css.js +242 -5
  11. package/dist/cjs/material/NiceMaterialEditor.js +1213 -757
  12. package/dist/cjs/material/materialEditorTypes.js +35 -49
  13. package/dist/cjs/material/materialEditorUtils.js +684 -747
  14. package/dist/cjs/material/materialNodeDefinitions.js +1411 -1459
  15. package/dist/cjs/model/ModelEditor.js +90 -40
  16. package/dist/cjs/model/ModelEditor.module.css.js +257 -5
  17. package/dist/cjs/model/ModelEditorLeftPanel.js +126 -47
  18. package/dist/cjs/model/ModelEditorMenuBar.js +359 -32
  19. package/dist/cjs/model/ModelEditorRightPanel.js +647 -131
  20. package/dist/cjs/model/ModelEditorSubComponents.js +277 -112
  21. package/dist/cjs/model/ModelEditorTimeline.js +232 -34
  22. package/dist/cjs/model/ModelEditorToolbar.js +170 -14
  23. package/dist/cjs/model/ModelEditorViewport.js +231 -39
  24. package/dist/cjs/model/ModelViewer.js +388 -63
  25. package/dist/cjs/model/ModelViewer.module.css.js +77 -5
  26. package/dist/cjs/model/NiceArmatureEditor.js +473 -274
  27. package/dist/cjs/model/NiceMorphTargetEditor.js +333 -227
  28. package/dist/cjs/model/NiceOctree.js +372 -320
  29. package/dist/cjs/model/NicePhysicsSimulation.js +528 -298
  30. package/dist/cjs/model/NiceProceduralGeometry.js +673 -300
  31. package/dist/cjs/model/NiceTerrainEditor.js +595 -385
  32. package/dist/cjs/model/NiceWeightPainter.js +384 -261
  33. package/dist/cjs/model/NiceXRPreview.js +385 -308
  34. package/dist/cjs/model/cadModeUtils.js +103 -106
  35. package/dist/cjs/model/editorShortcuts.js +171 -194
  36. package/dist/cjs/model/modelEditorTypes.js +100 -118
  37. package/dist/cjs/model/modelEditorUtils.js +1061 -1146
  38. package/dist/cjs/model/simsModeUtils.js +1023 -1053
  39. package/dist/cjs/model/useModelEditor.js +1977 -1933
  40. package/dist/cjs/model/useModelViewer.js +633 -665
  41. package/dist/cjs/nice2dev-ui-3d.css +1 -1
  42. package/dist/cjs/particle/NiceParticleEditor.js +1186 -571
  43. package/dist/cjs/particle/ParticleEditor.module.css.js +122 -5
  44. package/dist/cjs/particle/particleEditorTypes.js +62 -70
  45. package/dist/cjs/particle/particleEditorUtils.js +998 -1013
  46. package/dist/cjs/rendering/NiceCascadedShadows.js +381 -259
  47. package/dist/cjs/rendering/NiceRenderExport.js +424 -337
  48. package/dist/cjs/rendering/NiceSSAO.js +454 -337
  49. package/dist/cjs/rendering/NiceSSR.js +387 -261
  50. package/dist/cjs/rendering/NiceWebGPURenderer.js +359 -230
  51. package/dist/cjs/uv/NiceUVEditor.js +787 -550
  52. package/dist/cjs/uv/UVEditor.module.css.js +53 -5
  53. package/dist/cjs/uv/uvEditorTypes.js +59 -76
  54. package/dist/cjs/uv/uvEditorUtils.js +501 -575
  55. package/dist/esm/collaborative/collaborativeScene.js +163 -205
  56. package/dist/esm/core/editorAsk.js +53 -40
  57. package/dist/esm/core/i18n.js +15 -13
  58. package/dist/esm/core/threeCompat.js +18 -26
  59. package/dist/esm/dance/DanceBridge.js +151 -176
  60. package/dist/esm/dance/DanceScoreEngine.js +211 -220
  61. package/dist/esm/dance/PoseDetector.js +304 -274
  62. package/dist/esm/index.js +258 -36
  63. package/dist/esm/material/MaterialEditor.module.css.js +242 -3
  64. package/dist/esm/material/NiceMaterialEditor.js +1215 -756
  65. package/dist/esm/material/materialEditorTypes.js +45 -48
  66. package/dist/esm/material/materialEditorUtils.js +713 -746
  67. package/dist/esm/material/materialNodeDefinitions.js +1415 -1458
  68. package/dist/esm/model/ModelEditor.js +91 -39
  69. package/dist/esm/model/ModelEditor.module.css.js +257 -3
  70. package/dist/esm/model/ModelEditorLeftPanel.js +126 -45
  71. package/dist/esm/model/ModelEditorMenuBar.js +359 -30
  72. package/dist/esm/model/ModelEditorRightPanel.js +634 -114
  73. package/dist/esm/model/ModelEditorSubComponents.js +265 -94
  74. package/dist/esm/model/ModelEditorTimeline.js +232 -32
  75. package/dist/esm/model/ModelEditorToolbar.js +170 -12
  76. package/dist/esm/model/ModelEditorViewport.js +231 -37
  77. package/dist/esm/model/ModelViewer.js +389 -62
  78. package/dist/esm/model/ModelViewer.module.css.js +77 -3
  79. package/dist/esm/model/NiceArmatureEditor.js +462 -258
  80. package/dist/esm/model/NiceMorphTargetEditor.js +322 -211
  81. package/dist/esm/model/NiceOctree.js +361 -304
  82. package/dist/esm/model/NicePhysicsSimulation.js +517 -282
  83. package/dist/esm/model/NiceProceduralGeometry.js +667 -284
  84. package/dist/esm/model/NiceTerrainEditor.js +584 -369
  85. package/dist/esm/model/NiceWeightPainter.js +373 -245
  86. package/dist/esm/model/NiceXRPreview.js +374 -292
  87. package/dist/esm/model/cadModeUtils.js +95 -88
  88. package/dist/esm/model/editorShortcuts.js +172 -193
  89. package/dist/esm/model/modelEditorTypes.js +90 -100
  90. package/dist/esm/model/modelEditorUtils.js +1056 -1128
  91. package/dist/esm/model/simsModeUtils.js +1021 -1035
  92. package/dist/esm/model/useModelEditor.js +1946 -1920
  93. package/dist/esm/model/useModelViewer.js +619 -647
  94. package/dist/esm/nice2dev-ui-3d.css +1 -1
  95. package/dist/esm/particle/NiceParticleEditor.js +1188 -570
  96. package/dist/esm/particle/ParticleEditor.module.css.js +122 -3
  97. package/dist/esm/particle/particleEditorTypes.js +69 -69
  98. package/dist/esm/particle/particleEditorUtils.js +1027 -1012
  99. package/dist/esm/rendering/NiceCascadedShadows.js +370 -243
  100. package/dist/esm/rendering/NiceRenderExport.js +413 -321
  101. package/dist/esm/rendering/NiceSSAO.js +450 -328
  102. package/dist/esm/rendering/NiceSSR.js +383 -252
  103. package/dist/esm/rendering/NiceWebGPURenderer.js +326 -214
  104. package/dist/esm/uv/NiceUVEditor.js +788 -549
  105. package/dist/esm/uv/UVEditor.module.css.js +53 -3
  106. package/dist/esm/uv/uvEditorTypes.js +68 -75
  107. package/dist/esm/uv/uvEditorUtils.js +515 -557
  108. package/package.json +7 -12
@@ -1,247 +1,376 @@
1
- 'use strict';
2
-
3
- var jsxRuntime = require('react/jsx-runtime');
4
- var ui = require('@nice2dev/ui');
5
- var React = require('react');
6
- var THREE = require('three');
7
- var i18n = require('../core/i18n.js');
8
- var threeCompat = require('../core/threeCompat.js');
9
-
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
25
+ const jsxRuntime = require("react/jsx-runtime");
26
+ const ui = require("@nice2dev/ui");
27
+ const React = require("react");
28
+ const THREE = require("three");
29
+ const i18n = require("../core/i18n.js");
30
+ const threeCompat = require("../core/threeCompat.js");
10
31
  function _interopNamespaceDefault(e) {
11
- var n = Object.create(null);
12
- if (e) {
13
- Object.keys(e).forEach(function (k) {
14
- if (k !== 'default') {
15
- var d = Object.getOwnPropertyDescriptor(e, k);
16
- Object.defineProperty(n, k, d.get ? d : {
17
- enumerable: true,
18
- get: function () { return e[k]; }
19
- });
20
- }
32
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
33
+ if (e) {
34
+ for (const k in e) {
35
+ if (k !== "default") {
36
+ const d = Object.getOwnPropertyDescriptor(e, k);
37
+ Object.defineProperty(n, k, d.get ? d : {
38
+ enumerable: true,
39
+ get: () => e[k]
21
40
  });
41
+ }
22
42
  }
23
- n.default = e;
24
- return Object.freeze(n);
43
+ }
44
+ n.default = e;
45
+ return Object.freeze(n);
25
46
  }
26
-
27
- var THREE__namespace = /*#__PURE__*/_interopNamespaceDefault(THREE);
28
-
29
- /* ── WebGPU detection ── */
47
+ const THREE__namespace = /* @__PURE__ */ _interopNamespaceDefault(THREE);
30
48
  async function detectWebGPU() {
31
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
32
- if (!('gpu' in navigator)) {
33
- return null;
49
+ if (!("gpu" in navigator)) {
50
+ return null;
51
+ }
52
+ try {
53
+ const adapter = await navigator.gpu.requestAdapter();
54
+ if (!adapter) {
55
+ return null;
56
+ }
57
+ const legacy = adapter;
58
+ const info = adapter.info ?? await legacy.requestAdapterInfo?.() ?? {};
59
+ const device = await adapter.requestDevice();
60
+ const features = [];
61
+ adapter.features.forEach((f) => features.push(f));
62
+ device.destroy();
63
+ return {
64
+ isWebGPU: true,
65
+ adapterName: info.device ?? "Unknown",
66
+ vendor: info.vendor ?? "Unknown",
67
+ architecture: info.architecture ?? "Unknown",
68
+ maxTextureDimension2D: adapter.limits?.maxTextureDimension2D ?? 8192,
69
+ maxBufferSize: adapter.limits?.maxBufferSize ?? 268435456,
70
+ maxComputeWorkgroupSize: adapter.limits?.maxComputeWorkgroupSizeX ?? 256,
71
+ features
72
+ };
73
+ } catch {
74
+ return null;
75
+ }
76
+ }
77
+ function useWebGPURenderer(canvas, scene, camera, width = 800, height = 600, onRendererReady) {
78
+ const [renderer, setRenderer] = React.useState(null);
79
+ const [isWebGPU, setIsWebGPU] = React.useState(false);
80
+ const [capabilities, setCapabilities] = React.useState(null);
81
+ const [isReady, setIsReady] = React.useState(false);
82
+ const [toneMapping, setToneMappingState] = React.useState(
83
+ THREE__namespace.ACESFilmicToneMapping
84
+ );
85
+ const [toneMappingExposure, setToneMappingExposureState] = React.useState(1);
86
+ const [outputColorSpace, setOutputColorSpaceState] = React.useState(THREE__namespace.SRGBColorSpace);
87
+ const [pixelRatio, setPixelRatioState] = React.useState(
88
+ typeof window !== "undefined" ? window.devicePixelRatio : 1
89
+ );
90
+ const rendererRef = React.useRef(null);
91
+ React.useEffect(() => {
92
+ if (!canvas) {
93
+ return;
34
94
  }
35
- try {
36
- const adapter = await navigator.gpu.requestAdapter();
37
- if (!adapter) {
38
- return null;
95
+ let disposed = false;
96
+ async function init() {
97
+ const gpuCaps = await detectWebGPU();
98
+ if (disposed) {
99
+ return;
100
+ }
101
+ let r;
102
+ let usingWebGPU = false;
103
+ if (gpuCaps) {
104
+ try {
105
+ const { WebGPURenderer } = await import("three/webgpu").catch(() => ({
106
+ WebGPURenderer: null
107
+ }));
108
+ if (WebGPURenderer && !disposed) {
109
+ r = new WebGPURenderer({ canvas, antialias: true });
110
+ usingWebGPU = true;
111
+ } else {
112
+ r = new THREE__namespace.WebGLRenderer({
113
+ canvas: canvas ?? void 0,
114
+ antialias: true,
115
+ alpha: true
116
+ });
117
+ }
118
+ } catch {
119
+ r = new THREE__namespace.WebGLRenderer({
120
+ canvas: canvas ?? void 0,
121
+ antialias: true,
122
+ alpha: true
123
+ });
39
124
  }
40
- // `requestAdapterInfo()` was dropped from the WebGPU spec in favour of the
41
- // `info` property. Keep the old call as a runtime fallback for browsers that
42
- // still ship only the method.
43
- const legacy = adapter;
44
- const info = (_c = (_a = adapter.info) !== null && _a !== void 0 ? _a : (await ((_b = legacy.requestAdapterInfo) === null || _b === void 0 ? void 0 : _b.call(legacy)))) !== null && _c !== void 0 ? _c : {};
45
- const device = await adapter.requestDevice();
46
- const features = [];
47
- adapter.features.forEach((f) => features.push(f));
48
- device.destroy();
49
- return {
50
- isWebGPU: true,
51
- adapterName: (_d = info.device) !== null && _d !== void 0 ? _d : 'Unknown',
52
- vendor: (_e = info.vendor) !== null && _e !== void 0 ? _e : 'Unknown',
53
- architecture: (_f = info.architecture) !== null && _f !== void 0 ? _f : 'Unknown',
54
- maxTextureDimension2D: (_h = (_g = adapter.limits) === null || _g === void 0 ? void 0 : _g.maxTextureDimension2D) !== null && _h !== void 0 ? _h : 8192,
55
- maxBufferSize: (_k = (_j = adapter.limits) === null || _j === void 0 ? void 0 : _j.maxBufferSize) !== null && _k !== void 0 ? _k : 268435456,
56
- maxComputeWorkgroupSize: (_m = (_l = adapter.limits) === null || _l === void 0 ? void 0 : _l.maxComputeWorkgroupSizeX) !== null && _m !== void 0 ? _m : 256,
57
- features,
58
- };
125
+ setCapabilities(gpuCaps);
126
+ } else {
127
+ r = new THREE__namespace.WebGLRenderer({ canvas: canvas ?? void 0, antialias: true, alpha: true });
128
+ setCapabilities({
129
+ isWebGPU: false,
130
+ adapterName: r.getContext().getParameter(r.getContext().RENDERER) ?? "WebGL",
131
+ vendor: r.getContext().getParameter(r.getContext().VENDOR) ?? "Unknown",
132
+ architecture: "WebGL 2",
133
+ maxTextureDimension2D: r.getContext().getParameter(r.getContext().MAX_TEXTURE_SIZE),
134
+ maxBufferSize: 0,
135
+ maxComputeWorkgroupSize: 0,
136
+ features: []
137
+ });
138
+ }
139
+ if (disposed) {
140
+ r.dispose();
141
+ return;
142
+ }
143
+ r.setSize(width, height);
144
+ r.setPixelRatio(pixelRatio);
145
+ r.toneMapping = toneMapping;
146
+ r.toneMappingExposure = toneMappingExposure;
147
+ r.outputColorSpace = outputColorSpace;
148
+ r.shadowMap.enabled = true;
149
+ r.shadowMap.type = threeCompat.SOFT_SHADOW_MAP;
150
+ rendererRef.current = r;
151
+ setRenderer(r);
152
+ setIsWebGPU(usingWebGPU);
153
+ setIsReady(true);
154
+ onRendererReady?.(r, usingWebGPU);
59
155
  }
60
- catch (_o) {
61
- return null;
156
+ init();
157
+ return () => {
158
+ disposed = true;
159
+ rendererRef.current?.dispose();
160
+ };
161
+ }, [canvas]);
162
+ React.useEffect(() => {
163
+ if (!rendererRef.current) {
164
+ return;
165
+ }
166
+ rendererRef.current.toneMapping = toneMapping;
167
+ }, [toneMapping]);
168
+ React.useEffect(() => {
169
+ if (!rendererRef.current) {
170
+ return;
171
+ }
172
+ rendererRef.current.toneMappingExposure = toneMappingExposure;
173
+ }, [toneMappingExposure]);
174
+ React.useEffect(() => {
175
+ if (!rendererRef.current) {
176
+ return;
177
+ }
178
+ rendererRef.current.outputColorSpace = outputColorSpace;
179
+ }, [outputColorSpace]);
180
+ React.useEffect(() => {
181
+ if (!rendererRef.current) {
182
+ return;
62
183
  }
184
+ rendererRef.current.setPixelRatio(pixelRatio);
185
+ }, [pixelRatio]);
186
+ React.useEffect(() => {
187
+ if (!rendererRef.current) {
188
+ return;
189
+ }
190
+ rendererRef.current.setSize(width, height);
191
+ }, [width, height]);
192
+ const setToneMapping = React.useCallback((m) => {
193
+ setToneMappingState(m);
194
+ }, []);
195
+ const setToneMappingExposure = React.useCallback((e) => {
196
+ setToneMappingExposureState(e);
197
+ }, []);
198
+ const setOutputColorSpace = React.useCallback((s) => {
199
+ setOutputColorSpaceState(s);
200
+ }, []);
201
+ const setPixelRatio = React.useCallback((r) => {
202
+ setPixelRatioState(r);
203
+ }, []);
204
+ const dispose = React.useCallback(() => {
205
+ rendererRef.current?.dispose();
206
+ rendererRef.current = null;
207
+ setRenderer(null);
208
+ setIsReady(false);
209
+ }, []);
210
+ return {
211
+ renderer,
212
+ isWebGPU,
213
+ capabilities,
214
+ isReady,
215
+ toneMapping,
216
+ setToneMapping,
217
+ toneMappingExposure,
218
+ setToneMappingExposure,
219
+ outputColorSpace,
220
+ setOutputColorSpace,
221
+ pixelRatio,
222
+ setPixelRatio,
223
+ dispose
224
+ };
63
225
  }
64
- /* ── Hook ── */
65
- function useWebGPURenderer(canvas, scene, camera, width = 800, height = 600, onRendererReady) {
66
- const [renderer, setRenderer] = React.useState(null);
67
- const [isWebGPU, setIsWebGPU] = React.useState(false);
68
- const [capabilities, setCapabilities] = React.useState(null);
69
- const [isReady, setIsReady] = React.useState(false);
70
- const [toneMapping, setToneMappingState] = React.useState(THREE__namespace.ACESFilmicToneMapping);
71
- const [toneMappingExposure, setToneMappingExposureState] = React.useState(1.0);
72
- const [outputColorSpace, setOutputColorSpaceState] = React.useState(THREE__namespace.SRGBColorSpace);
73
- const [pixelRatio, setPixelRatioState] = React.useState(typeof window !== 'undefined' ? window.devicePixelRatio : 1);
74
- const rendererRef = React.useRef(null);
75
- // Initialize renderer
76
- React.useEffect(() => {
77
- if (!canvas) {
78
- return;
79
- }
80
- let disposed = false;
81
- async function init() {
82
- var _a, _b;
83
- const gpuCaps = await detectWebGPU();
84
- if (disposed) {
85
- return;
226
+ const TONE_MAPPINGS = [
227
+ { value: THREE__namespace.NoToneMapping, label: "None" },
228
+ { value: THREE__namespace.LinearToneMapping, label: "Linear" },
229
+ { value: THREE__namespace.ReinhardToneMapping, label: "Reinhard" },
230
+ { value: THREE__namespace.CineonToneMapping, label: "Cineon" },
231
+ { value: THREE__namespace.ACESFilmicToneMapping, label: "ACES Filmic" },
232
+ { value: THREE__namespace.AgXToneMapping, label: "AgX" },
233
+ { value: THREE__namespace.NeutralToneMapping, label: "Neutral" }
234
+ ];
235
+ const NiceWebGPURenderer = ({
236
+ canvas,
237
+ scene,
238
+ camera,
239
+ width,
240
+ height,
241
+ onRendererReady,
242
+ className = ""
243
+ }) => {
244
+ const { t } = i18n.useNiceTranslation();
245
+ const {
246
+ isWebGPU,
247
+ capabilities,
248
+ isReady,
249
+ toneMapping,
250
+ setToneMapping,
251
+ toneMappingExposure,
252
+ setToneMappingExposure,
253
+ outputColorSpace,
254
+ setOutputColorSpace,
255
+ pixelRatio,
256
+ setPixelRatio
257
+ } = useWebGPURenderer(canvas, scene, camera, width, height, onRendererReady);
258
+ return /* @__PURE__ */ jsxRuntime.jsxs(
259
+ "div",
260
+ {
261
+ className: `nice-webgpu-renderer ${className}`,
262
+ style: { display: "grid", gap: 8, fontSize: 13 },
263
+ children: [
264
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
265
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
266
+ /* @__PURE__ */ jsxRuntime.jsx(ui.NiceIcon, { name: "monitor", size: 14 }),
267
+ " ",
268
+ t("webGPURenderer.renderer", "Renderer")
269
+ ] }),
270
+ /* @__PURE__ */ jsxRuntime.jsx(
271
+ "span",
272
+ {
273
+ style: {
274
+ fontSize: 10,
275
+ padding: "2px 6px",
276
+ borderRadius: 4,
277
+ background: isWebGPU ? "var(--nice-success, #22c55e)" : "var(--nice-warning, #f59e0b)",
278
+ color: "var(--nice-color-white, #fff)"
279
+ },
280
+ children: isWebGPU ? "WebGPU" : "WebGL"
86
281
  }
87
- let r;
88
- let usingWebGPU = false;
89
- if (gpuCaps) {
90
- // Try the WebGPU renderer. Since three r167 it lives in the `three/webgpu` entry; the
91
- // old `examples/jsm/renderers/webgpu/WebGPURenderer.js` path no longer exists, and a
92
- // bundler that cannot resolve a literal dynamic import fails the whole module.
93
- try {
94
- const { WebGPURenderer } = await import('three/webgpu').catch(() => ({
95
- WebGPURenderer: null,
96
- }));
97
- if (WebGPURenderer && !disposed) {
98
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Three.js WebGPU renderer is loaded via dynamic import; constructor signature mirrors WebGLRenderer
99
- r = new WebGPURenderer({ canvas, antialias: true });
100
- usingWebGPU = true;
101
- }
102
- else {
103
- r = new THREE__namespace.WebGLRenderer({
104
- canvas: canvas !== null && canvas !== void 0 ? canvas : undefined,
105
- antialias: true,
106
- alpha: true,
107
- });
108
- }
109
- }
110
- catch (_c) {
111
- r = new THREE__namespace.WebGLRenderer({
112
- canvas: canvas !== null && canvas !== void 0 ? canvas : undefined,
113
- antialias: true,
114
- alpha: true,
115
- });
116
- }
117
- setCapabilities(gpuCaps);
282
+ )
283
+ ] }),
284
+ !isReady && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { opacity: 0.6, fontSize: 11 }, children: t("webGPURenderer.initializing", "Initializing…") }),
285
+ capabilities && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 10, opacity: 0.7, lineHeight: 1.5 }, children: [
286
+ t("webGPURenderer.gpu", "GPU: {adapterName}").replace(
287
+ "{adapterName}",
288
+ String(capabilities.adapterName)
289
+ ),
290
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
291
+ t("webGPURenderer.vendor", "Vendor: {vendor}").replace(
292
+ "{vendor}",
293
+ String(capabilities.vendor)
294
+ ),
295
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
296
+ t("webGPURenderer.maxTexturePx", "Max Texture: {maxTextureDimension2D}px").replace(
297
+ "{maxTextureDimension2D}",
298
+ String(capabilities.maxTextureDimension2D)
299
+ ),
300
+ capabilities.features.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
301
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
302
+ t("webGPURenderer.features", "Features: {features}").replace(
303
+ "{features}",
304
+ String(capabilities.features.length)
305
+ )
306
+ ] })
307
+ ] }),
308
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
309
+ t("webGPURenderer.toneMapping", "Tone Mapping:"),
310
+ /* @__PURE__ */ jsxRuntime.jsx(
311
+ "select",
312
+ {
313
+ value: toneMapping,
314
+ onChange: (e) => setToneMapping(parseInt(e.target.value, 10)),
315
+ style: { width: "100%", marginTop: 2 },
316
+ children: TONE_MAPPINGS.map((tm) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: tm.value, children: tm.label }, tm.value))
118
317
  }
119
- else {
120
- r = new THREE__namespace.WebGLRenderer({ canvas: canvas !== null && canvas !== void 0 ? canvas : undefined, antialias: true, alpha: true });
121
- setCapabilities({
122
- isWebGPU: false,
123
- adapterName: (_a = r.getContext().getParameter(r.getContext().RENDERER)) !== null && _a !== void 0 ? _a : 'WebGL',
124
- vendor: (_b = r.getContext().getParameter(r.getContext().VENDOR)) !== null && _b !== void 0 ? _b : 'Unknown',
125
- architecture: 'WebGL 2',
126
- maxTextureDimension2D: r.getContext().getParameter(r.getContext().MAX_TEXTURE_SIZE),
127
- maxBufferSize: 0,
128
- maxComputeWorkgroupSize: 0,
129
- features: [],
130
- });
318
+ )
319
+ ] }),
320
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
321
+ t("webGPURenderer.exposure", "Exposure: {toneMappingExposure}").replace(
322
+ "{toneMappingExposure}",
323
+ String(toneMappingExposure.toFixed(2))
324
+ ),
325
+ /* @__PURE__ */ jsxRuntime.jsx(
326
+ "input",
327
+ {
328
+ type: "range",
329
+ min: 0.1,
330
+ max: 3,
331
+ step: 0.05,
332
+ value: toneMappingExposure,
333
+ onChange: (e) => setToneMappingExposure(parseFloat(e.target.value)),
334
+ style: { width: "100%" }
131
335
  }
132
- if (disposed) {
133
- r.dispose();
134
- return;
336
+ )
337
+ ] }),
338
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
339
+ t("webGPURenderer.outputColorSpace", "Output Color Space:"),
340
+ /* @__PURE__ */ jsxRuntime.jsxs(
341
+ "select",
342
+ {
343
+ value: outputColorSpace,
344
+ onChange: (e) => setOutputColorSpace(e.target.value),
345
+ style: { width: "100%", marginTop: 2 },
346
+ children: [
347
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: THREE__namespace.SRGBColorSpace, children: "sRGB" }),
348
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: THREE__namespace.LinearSRGBColorSpace, children: t("webGPURenderer.linearSrgb", "Linear sRGB") })
349
+ ]
135
350
  }
136
- r.setSize(width, height);
137
- r.setPixelRatio(pixelRatio);
138
- r.toneMapping = toneMapping;
139
- r.toneMappingExposure = toneMappingExposure;
140
- r.outputColorSpace = outputColorSpace;
141
- r.shadowMap.enabled = true;
142
- r.shadowMap.type = threeCompat.SOFT_SHADOW_MAP;
143
- rendererRef.current = r;
144
- setRenderer(r);
145
- setIsWebGPU(usingWebGPU);
146
- setIsReady(true);
147
- onRendererReady === null || onRendererReady === void 0 ? void 0 : onRendererReady(r, usingWebGPU);
148
- }
149
- init();
150
- return () => {
151
- var _a;
152
- disposed = true;
153
- (_a = rendererRef.current) === null || _a === void 0 ? void 0 : _a.dispose();
154
- };
155
- // eslint-disable-next-line react-hooks/exhaustive-deps -- one renderer per canvas, made with the first settings; the effects below apply later changes, and onRendererReady reports that one renderer
156
- }, [canvas]);
157
- // Update renderer settings reactively
158
- React.useEffect(() => {
159
- if (!rendererRef.current) {
160
- return;
161
- }
162
- rendererRef.current.toneMapping = toneMapping;
163
- }, [toneMapping]);
164
- React.useEffect(() => {
165
- if (!rendererRef.current) {
166
- return;
167
- }
168
- rendererRef.current.toneMappingExposure = toneMappingExposure;
169
- }, [toneMappingExposure]);
170
- React.useEffect(() => {
171
- if (!rendererRef.current) {
172
- return;
173
- }
174
- rendererRef.current.outputColorSpace = outputColorSpace;
175
- }, [outputColorSpace]);
176
- React.useEffect(() => {
177
- if (!rendererRef.current) {
178
- return;
179
- }
180
- rendererRef.current.setPixelRatio(pixelRatio);
181
- }, [pixelRatio]);
182
- React.useEffect(() => {
183
- if (!rendererRef.current) {
184
- return;
185
- }
186
- rendererRef.current.setSize(width, height);
187
- }, [width, height]);
188
- const setToneMapping = React.useCallback((m) => {
189
- setToneMappingState(m);
190
- }, []);
191
- const setToneMappingExposure = React.useCallback((e) => {
192
- setToneMappingExposureState(e);
193
- }, []);
194
- const setOutputColorSpace = React.useCallback((s) => {
195
- setOutputColorSpaceState(s);
196
- }, []);
197
- const setPixelRatio = React.useCallback((r) => {
198
- setPixelRatioState(r);
199
- }, []);
200
- const dispose = React.useCallback(() => {
201
- var _a;
202
- (_a = rendererRef.current) === null || _a === void 0 ? void 0 : _a.dispose();
203
- rendererRef.current = null;
204
- setRenderer(null);
205
- setIsReady(false);
206
- }, []);
207
- return {
208
- renderer,
209
- isWebGPU,
210
- capabilities,
211
- isReady,
212
- toneMapping,
213
- setToneMapping,
214
- toneMappingExposure,
215
- setToneMappingExposure,
216
- outputColorSpace,
217
- setOutputColorSpace,
218
- pixelRatio,
219
- setPixelRatio,
220
- dispose,
221
- };
222
- }
223
- /* ── Tone mapping options ── */
224
- const TONE_MAPPINGS = [
225
- { value: THREE__namespace.NoToneMapping, label: 'None' },
226
- { value: THREE__namespace.LinearToneMapping, label: 'Linear' },
227
- { value: THREE__namespace.ReinhardToneMapping, label: 'Reinhard' },
228
- { value: THREE__namespace.CineonToneMapping, label: 'Cineon' },
229
- { value: THREE__namespace.ACESFilmicToneMapping, label: 'ACES Filmic' },
230
- { value: THREE__namespace.AgXToneMapping, label: 'AgX' },
231
- { value: THREE__namespace.NeutralToneMapping, label: 'Neutral' },
232
- ];
233
- /* ── Component ── */
234
- const NiceWebGPURenderer = ({ canvas, scene, camera, width, height, onRendererReady, className = '', }) => {
235
- const { t } = i18n.useNiceTranslation();
236
- const { isWebGPU, capabilities, isReady, toneMapping, setToneMapping, toneMappingExposure, setToneMappingExposure, outputColorSpace, setOutputColorSpace, pixelRatio, setPixelRatio, } = useWebGPURenderer(canvas, scene, camera, width, height, onRendererReady);
237
- return (jsxRuntime.jsxs("div", { className: `nice-webgpu-renderer ${className}`, style: { display: 'grid', gap: 8, fontSize: 13 }, children: [jsxRuntime.jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' }, children: [jsxRuntime.jsxs("strong", { children: [jsxRuntime.jsx(ui.NiceIcon, { name: "monitor", size: 14 }), " ", t('webGPURenderer.renderer', 'Renderer')] }), jsxRuntime.jsx("span", { style: {
238
- fontSize: 10,
239
- padding: '2px 6px',
240
- borderRadius: 4,
241
- background: isWebGPU ? 'var(--nice-success, #22c55e)' : 'var(--nice-warning, #f59e0b)',
242
- color: 'var(--nice-color-white, #fff)',
243
- }, children: isWebGPU ? 'WebGPU' : 'WebGL' })] }), !isReady && (jsxRuntime.jsx("div", { style: { opacity: 0.6, fontSize: 11 }, children: t('webGPURenderer.initializing', 'Initializing…') })), capabilities && (jsxRuntime.jsxs("div", { style: { fontSize: 10, opacity: 0.7, lineHeight: 1.5 }, children: [t('webGPURenderer.gpu', 'GPU: {adapterName}').replace('{adapterName}', String(capabilities.adapterName)), jsxRuntime.jsx("br", {}), t('webGPURenderer.vendor', 'Vendor: {vendor}').replace('{vendor}', String(capabilities.vendor)), jsxRuntime.jsx("br", {}), t('webGPURenderer.maxTexturePx', 'Max Texture: {maxTextureDimension2D}px').replace('{maxTextureDimension2D}', String(capabilities.maxTextureDimension2D)), capabilities.features.length > 0 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("br", {}), t('webGPURenderer.features', 'Features: {features}').replace('{features}', String(capabilities.features.length))] }))] })), jsxRuntime.jsxs("label", { children: [t('webGPURenderer.toneMapping', 'Tone Mapping:'), jsxRuntime.jsx("select", { value: toneMapping, onChange: (e) => setToneMapping(parseInt(e.target.value, 10)), style: { width: '100%', marginTop: 2 }, children: TONE_MAPPINGS.map((tm) => (jsxRuntime.jsx("option", { value: tm.value, children: tm.label }, tm.value))) })] }), jsxRuntime.jsxs("label", { children: [t('webGPURenderer.exposure', 'Exposure: {toneMappingExposure}').replace('{toneMappingExposure}', String(toneMappingExposure.toFixed(2))), jsxRuntime.jsx("input", { type: "range", min: 0.1, max: 3, step: 0.05, value: toneMappingExposure, onChange: (e) => setToneMappingExposure(parseFloat(e.target.value)), style: { width: '100%' } })] }), jsxRuntime.jsxs("label", { children: [t('webGPURenderer.outputColorSpace', 'Output Color Space:'), jsxRuntime.jsxs("select", { value: outputColorSpace, onChange: (e) => setOutputColorSpace(e.target.value), style: { width: '100%', marginTop: 2 }, children: [jsxRuntime.jsx("option", { value: THREE__namespace.SRGBColorSpace, children: "sRGB" }), jsxRuntime.jsx("option", { value: THREE__namespace.LinearSRGBColorSpace, children: t('webGPURenderer.linearSrgb', 'Linear sRGB') })] })] }), jsxRuntime.jsxs("label", { children: [t('webGPURenderer.pixelRatio', 'Pixel Ratio: {pixelRatio}').replace('{pixelRatio}', String(pixelRatio.toFixed(1))), jsxRuntime.jsx("input", { type: "range", min: 0.5, max: 3, step: 0.5, value: pixelRatio, onChange: (e) => setPixelRatio(parseFloat(e.target.value)), style: { width: '100%' } })] })] }));
351
+ )
352
+ ] }),
353
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
354
+ t("webGPURenderer.pixelRatio", "Pixel Ratio: {pixelRatio}").replace(
355
+ "{pixelRatio}",
356
+ String(pixelRatio.toFixed(1))
357
+ ),
358
+ /* @__PURE__ */ jsxRuntime.jsx(
359
+ "input",
360
+ {
361
+ type: "range",
362
+ min: 0.5,
363
+ max: 3,
364
+ step: 0.5,
365
+ value: pixelRatio,
366
+ onChange: (e) => setPixelRatio(parseFloat(e.target.value)),
367
+ style: { width: "100%" }
368
+ }
369
+ )
370
+ ] })
371
+ ]
372
+ }
373
+ );
244
374
  };
245
-
246
375
  exports.NiceWebGPURenderer = NiceWebGPURenderer;
247
376
  exports.useWebGPURenderer = useWebGPURenderer;