@holoscript/core 6.0.4 → 7.0.0

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 (236) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -1
  3. package/dist/compiler/index.d.ts +82 -0
  4. package/dist/constants.d.ts +3 -2
  5. package/dist/coordinators/index.d.ts +189 -0
  6. package/dist/index.d.ts +501 -19
  7. package/dist/paper-0c-spike/index.d.ts +29 -0
  8. package/dist/reconstruction/index.d.ts +78 -0
  9. package/dist/tools/index.d.ts +22 -1
  10. package/dist/traitDocs/traitDocs.d.ts +69 -0
  11. package/dist/traits/index.d.ts +61 -0
  12. package/package.json +105 -57
  13. package/dist/GLTFPipeline-DEN36VNK.js +0 -12
  14. package/dist/GLTFPipeline-YPCAK236.cjs +0 -33
  15. package/dist/HoloScriptPlusParser-BN6KVRCM.js +0 -692
  16. package/dist/HoloScriptPlusParser-NC5FE6AL.cjs +0 -697
  17. package/dist/USDZExporter-NTMBNTDB.js +0 -707
  18. package/dist/USDZExporter-UWGWNMMD.cjs +0 -709
  19. package/dist/chunk-27LWW5FU.cjs +0 -410
  20. package/dist/chunk-2CWOLHTE.js +0 -69
  21. package/dist/chunk-33LSUQDD.cjs +0 -835
  22. package/dist/chunk-3FJCK5XA.js +0 -2232
  23. package/dist/chunk-3FXV5S25.cjs +0 -633
  24. package/dist/chunk-3FYZOR7S.cjs +0 -69
  25. package/dist/chunk-3SAK5KFL.cjs +0 -83
  26. package/dist/chunk-4XSNJCLC.cjs +0 -1859
  27. package/dist/chunk-54FHG2MX.js +0 -655
  28. package/dist/chunk-56IF4NTA.js +0 -56
  29. package/dist/chunk-5BGSECRJ.cjs +0 -2237
  30. package/dist/chunk-5GLCTO44.js +0 -161
  31. package/dist/chunk-5O6TQC6M.cjs +0 -1871
  32. package/dist/chunk-5OEOHAAW.cjs +0 -682
  33. package/dist/chunk-5TOFIR6L.js +0 -407
  34. package/dist/chunk-5WUNN6ZN.cjs +0 -428
  35. package/dist/chunk-6TZPZCOJ.cjs +0 -1404
  36. package/dist/chunk-6UEHYZ7V.cjs +0 -773
  37. package/dist/chunk-6XSERL6L.js +0 -5678
  38. package/dist/chunk-72EQECGT.cjs +0 -908
  39. package/dist/chunk-7AGYRWKW.cjs +0 -507
  40. package/dist/chunk-7LCYLPW2.cjs +0 -663
  41. package/dist/chunk-A7PIMZGU.js +0 -263
  42. package/dist/chunk-ATSKSYVE.cjs +0 -51683
  43. package/dist/chunk-B5TCIAPQ.cjs +0 -117
  44. package/dist/chunk-BF2235SI.cjs +0 -5714
  45. package/dist/chunk-BKIGPPVM.js +0 -629
  46. package/dist/chunk-BND3ST2K.cjs +0 -662
  47. package/dist/chunk-BU7VWW2K.js +0 -2522
  48. package/dist/chunk-BWFJEM5A.js +0 -5419
  49. package/dist/chunk-CAUCGUEA.cjs +0 -130
  50. package/dist/chunk-CBJSLA2E.cjs +0 -5423
  51. package/dist/chunk-CDPGV4DN.js +0 -114
  52. package/dist/chunk-CLYEIWA5.cjs +0 -408
  53. package/dist/chunk-CS2EMTGF.js +0 -1966
  54. package/dist/chunk-DMG7C4H2.js +0 -975
  55. package/dist/chunk-DXJQDCFL.js +0 -468
  56. package/dist/chunk-E3FWRT3Z.js +0 -608
  57. package/dist/chunk-E3UALNFA.js +0 -421
  58. package/dist/chunk-EONILVMF.js +0 -762
  59. package/dist/chunk-EQV4R3EV.cjs +0 -769
  60. package/dist/chunk-F3HH56EB.cjs +0 -5538
  61. package/dist/chunk-F4IULT7N.js +0 -1488
  62. package/dist/chunk-FF3Q7ADR.js +0 -380
  63. package/dist/chunk-FFKU7BTK.cjs +0 -1046
  64. package/dist/chunk-FHQVYCH2.js +0 -70
  65. package/dist/chunk-FSF7EQVA.cjs +0 -1974
  66. package/dist/chunk-G4VZTCIB.js +0 -659
  67. package/dist/chunk-G7CT3EMP.cjs +0 -1002
  68. package/dist/chunk-GGHSW2NN.js +0 -51334
  69. package/dist/chunk-GVUR45UF.cjs +0 -777
  70. package/dist/chunk-H5Z7NASB.js +0 -9662
  71. package/dist/chunk-HE7ULERA.cjs +0 -697
  72. package/dist/chunk-HJJLD366.js +0 -1169
  73. package/dist/chunk-HPS76H7Q.js +0 -309
  74. package/dist/chunk-HQUEA5R6.cjs +0 -424
  75. package/dist/chunk-HYNTS5CP.js +0 -422
  76. package/dist/chunk-I6XZ5DZF.cjs +0 -488
  77. package/dist/chunk-IBDG74G2.cjs +0 -1219
  78. package/dist/chunk-IFNQFCTM.js +0 -3098
  79. package/dist/chunk-IHOUYQIA.js +0 -406
  80. package/dist/chunk-ILRBGFVD.cjs +0 -72
  81. package/dist/chunk-IWI6J7FX.js +0 -421
  82. package/dist/chunk-K3JDKWGI.cjs +0 -270
  83. package/dist/chunk-K6EKD26I.js +0 -630
  84. package/dist/chunk-KCQ5NDYC.cjs +0 -3172
  85. package/dist/chunk-KED34ILP.js +0 -832
  86. package/dist/chunk-KSGXLT74.cjs +0 -457
  87. package/dist/chunk-L4G4RLXX.js +0 -767
  88. package/dist/chunk-LDP5OK6G.js +0 -1216
  89. package/dist/chunk-LGGRPKTV.cjs +0 -735
  90. package/dist/chunk-LK5IAVH6.cjs +0 -1173
  91. package/dist/chunk-LSW7P7ML.js +0 -3675
  92. package/dist/chunk-LXJ4667L.cjs +0 -3874
  93. package/dist/chunk-LZ266PCM.cjs +0 -4499
  94. package/dist/chunk-MD6KDHVE.cjs +0 -237
  95. package/dist/chunk-MEASWI2Y.js +0 -126
  96. package/dist/chunk-MPXBVFHQ.js +0 -768
  97. package/dist/chunk-N5FTS757.cjs +0 -415
  98. package/dist/chunk-NCUKG4SK.cjs +0 -3075
  99. package/dist/chunk-NDQNIJEH.js +0 -1715
  100. package/dist/chunk-NOZZ46QU.js +0 -168
  101. package/dist/chunk-OFKWH2IP.js +0 -449
  102. package/dist/chunk-PHENW4MQ.js +0 -65
  103. package/dist/chunk-PMGODDJA.cjs +0 -319
  104. package/dist/chunk-Q4QX3AET.cjs +0 -1505
  105. package/dist/chunk-Q56TT7IL.js +0 -483
  106. package/dist/chunk-Q5JT3YML.cjs +0 -129
  107. package/dist/chunk-Q5SJOGHQ.cjs +0 -4256
  108. package/dist/chunk-QGKNANZ3.js +0 -3071
  109. package/dist/chunk-QLEAOI3Q.cjs +0 -424
  110. package/dist/chunk-R7MA7QWV.js +0 -732
  111. package/dist/chunk-RVYPEYPX.js +0 -678
  112. package/dist/chunk-S2N5TNMA.js +0 -1855
  113. package/dist/chunk-S565K7NK.js +0 -752
  114. package/dist/chunk-SDAMZIRE.js +0 -765
  115. package/dist/chunk-T36DDXSF.js +0 -4250
  116. package/dist/chunk-T4NKMBDL.js +0 -5474
  117. package/dist/chunk-T7LEXZUZ.cjs +0 -2526
  118. package/dist/chunk-TEWCN33Y.js +0 -694
  119. package/dist/chunk-TQSZUOW5.cjs +0 -793
  120. package/dist/chunk-TSH3MSQU.cjs +0 -129
  121. package/dist/chunk-UERJ3YJV.js +0 -504
  122. package/dist/chunk-UPJBDCVF.js +0 -1395
  123. package/dist/chunk-V3NN3HPP.js +0 -4462
  124. package/dist/chunk-VJ3L7CHT.cjs +0 -169
  125. package/dist/chunk-WB4Z63GG.js +0 -229
  126. package/dist/chunk-WDW67DZB.cjs +0 -9728
  127. package/dist/chunk-WGMEAYBG.js +0 -126
  128. package/dist/chunk-X4ZF6CNE.cjs +0 -473
  129. package/dist/chunk-X6SEAXAX.cjs +0 -3681
  130. package/dist/chunk-XCWFGZAA.js +0 -1043
  131. package/dist/chunk-XD6IYDUX.js +0 -903
  132. package/dist/chunk-XG23EUQX.cjs +0 -1717
  133. package/dist/chunk-XRKWN5PL.cjs +0 -173
  134. package/dist/chunk-XUILI4KB.cjs +0 -430
  135. package/dist/chunk-XUTX5CBW.js +0 -126
  136. package/dist/chunk-XWPNTWDN.cjs +0 -755
  137. package/dist/chunk-XXINBTZK.cjs +0 -633
  138. package/dist/chunk-YCXFCXDS.js +0 -1868
  139. package/dist/chunk-YQK5JNFK.js +0 -3725
  140. package/dist/chunk-YYXH45E2.js +0 -426
  141. package/dist/chunk-Z34RLXRA.cjs +0 -612
  142. package/dist/chunk-ZP4D3CSX.cjs +0 -72
  143. package/dist/cli/holoscript-runner.cjs +0 -2259
  144. package/dist/cli/holoscript-runner.js +0 -2234
  145. package/dist/codebase/index.cjs +0 -336
  146. package/dist/codebase/index.js +0 -331
  147. package/dist/compiler/agent-inference.cjs +0 -28
  148. package/dist/compiler/agent-inference.js +0 -5
  149. package/dist/compiler/android-xr.cjs +0 -19
  150. package/dist/compiler/android-xr.js +0 -9
  151. package/dist/compiler/android.cjs +0 -20
  152. package/dist/compiler/android.js +0 -10
  153. package/dist/compiler/ar.cjs +0 -20
  154. package/dist/compiler/ar.js +0 -8
  155. package/dist/compiler/babylon.cjs +0 -17
  156. package/dist/compiler/babylon.js +0 -11
  157. package/dist/compiler/coco.cjs +0 -27
  158. package/dist/compiler/coco.js +0 -4
  159. package/dist/compiler/domain-block-utils.cjs +0 -602
  160. package/dist/compiler/domain-block-utils.js +0 -8
  161. package/dist/compiler/dtdl.cjs +0 -24
  162. package/dist/compiler/dtdl.js +0 -8
  163. package/dist/compiler/gltf-pipeline.cjs +0 -39
  164. package/dist/compiler/gltf-pipeline.js +0 -4
  165. package/dist/compiler/godot.cjs +0 -15
  166. package/dist/compiler/godot.js +0 -9
  167. package/dist/compiler/incremental.cjs +0 -29
  168. package/dist/compiler/incremental.js +0 -4
  169. package/dist/compiler/index.cjs +0 -2578
  170. package/dist/compiler/index.js +0 -2383
  171. package/dist/compiler/ios.cjs +0 -20
  172. package/dist/compiler/ios.js +0 -10
  173. package/dist/compiler/multi-layer.cjs +0 -20
  174. package/dist/compiler/multi-layer.js +0 -11
  175. package/dist/compiler/nodetoy.cjs +0 -23
  176. package/dist/compiler/nodetoy.js +0 -4
  177. package/dist/compiler/openxr.cjs +0 -15
  178. package/dist/compiler/openxr.js +0 -9
  179. package/dist/compiler/playcanvas.cjs +0 -16
  180. package/dist/compiler/playcanvas.js +0 -10
  181. package/dist/compiler/r3f.cjs +0 -34
  182. package/dist/compiler/r3f.js +0 -12
  183. package/dist/compiler/remotion.cjs +0 -23
  184. package/dist/compiler/remotion.js +0 -4
  185. package/dist/compiler/reproducibility.cjs +0 -39
  186. package/dist/compiler/reproducibility.js +0 -4
  187. package/dist/compiler/sdf.cjs +0 -21
  188. package/dist/compiler/sdf.js +0 -9
  189. package/dist/compiler/semantic-scene.cjs +0 -31
  190. package/dist/compiler/semantic-scene.js +0 -4
  191. package/dist/compiler/state.cjs +0 -17
  192. package/dist/compiler/state.js +0 -7
  193. package/dist/compiler/trait-composition.cjs +0 -26
  194. package/dist/compiler/trait-composition.js +0 -5
  195. package/dist/compiler/unity.cjs +0 -15
  196. package/dist/compiler/unity.js +0 -9
  197. package/dist/compiler/unreal.cjs +0 -19
  198. package/dist/compiler/unreal.js +0 -9
  199. package/dist/compiler/urdf.cjs +0 -45
  200. package/dist/compiler/urdf.js +0 -9
  201. package/dist/compiler/usd-physics.cjs +0 -23
  202. package/dist/compiler/usd-physics.js +0 -6
  203. package/dist/compiler/visionos.cjs +0 -15
  204. package/dist/compiler/visionos.js +0 -9
  205. package/dist/compiler/vrchat.cjs +0 -19
  206. package/dist/compiler/vrchat.js +0 -9
  207. package/dist/compiler/vrr.cjs +0 -21
  208. package/dist/compiler/vrr.js +0 -9
  209. package/dist/compiler/wasm.cjs +0 -33
  210. package/dist/compiler/wasm.js +0 -9
  211. package/dist/compiler/webgpu.cjs +0 -15
  212. package/dist/compiler/webgpu.js +0 -9
  213. package/dist/debugger.cjs +0 -21
  214. package/dist/debugger.js +0 -8
  215. package/dist/entries/interop.cjs +0 -62
  216. package/dist/entries/interop.js +0 -5
  217. package/dist/entries/scripting.cjs +0 -68
  218. package/dist/entries/scripting.js +0 -11
  219. package/dist/index.cjs +0 -40921
  220. package/dist/index.js +0 -37763
  221. package/dist/math/vec3.cjs +0 -57
  222. package/dist/math/vec3.js +0 -4
  223. package/dist/ml-dsa-PHCWUBPX.cjs +0 -1178
  224. package/dist/ml-dsa-WYLJHJO6.js +0 -1178
  225. package/dist/parser.cjs +0 -27
  226. package/dist/parser.js +0 -10
  227. package/dist/playwright-5OSAPTNH.js +0 -98660
  228. package/dist/playwright-RL6GY4F7.cjs +0 -98673
  229. package/dist/runtime.cjs +0 -16
  230. package/dist/runtime.js +0 -7
  231. package/dist/storage/index.cjs +0 -37
  232. package/dist/storage/index.js +0 -4
  233. package/dist/traits/index.cjs +0 -14649
  234. package/dist/traits/index.js +0 -12243
  235. package/dist/type-checker.cjs +0 -18
  236. package/dist/type-checker.js +0 -5
@@ -1,1488 +0,0 @@
1
- // src/traits/LightingTrait.ts
2
- var LightingTrait = class {
3
- constructor(config) {
4
- this.lights = /* @__PURE__ */ new Map();
5
- this.lightIdCounter = 0;
6
- this.globalIllumination = {
7
- enabled: true,
8
- intensity: 1,
9
- skyColor: { r: 0.5, g: 0.7, b: 1 },
10
- skyIntensity: 1,
11
- groundColor: { r: 0.4, g: 0.4, b: 0.4 },
12
- groundIntensity: 0.5,
13
- probes: true,
14
- indirectDiffuse: 1,
15
- indirectSpecular: 1,
16
- aoIntensity: 1,
17
- screenSpaceAO: true,
18
- ...config
19
- };
20
- }
21
- /**
22
- * Add a light to the scene
23
- */
24
- addLight(light) {
25
- const id = light.name || `light_${this.lightIdCounter++}`;
26
- this.lights.set(id, light);
27
- return id;
28
- }
29
- /**
30
- * Get light by ID
31
- */
32
- getLight(id) {
33
- return this.lights.get(id);
34
- }
35
- /**
36
- * Get all lights
37
- */
38
- getLights() {
39
- return Array.from(this.lights.values());
40
- }
41
- /**
42
- * Get lights by type
43
- */
44
- getLightsByType(type) {
45
- return Array.from(this.lights.values()).filter((l) => l.type === type);
46
- }
47
- /**
48
- * Update light properties
49
- */
50
- updateLight(id, updates) {
51
- const light = this.lights.get(id);
52
- if (!light) return false;
53
- this.lights.set(id, { ...light, ...updates });
54
- return true;
55
- }
56
- /**
57
- * Remove light
58
- */
59
- removeLight(id) {
60
- return this.lights.delete(id);
61
- }
62
- /**
63
- * Clear all lights
64
- */
65
- clearLights() {
66
- this.lights.clear();
67
- }
68
- /**
69
- * Get global illumination config
70
- */
71
- getGlobalIllumination() {
72
- return { ...this.globalIllumination };
73
- }
74
- /**
75
- * Update global illumination
76
- */
77
- updateGlobalIllumination(updates) {
78
- this.globalIllumination = {
79
- ...this.globalIllumination,
80
- ...updates
81
- };
82
- }
83
- /**
84
- * Enable/disable GI
85
- */
86
- setGIEnabled(enabled) {
87
- this.globalIllumination.enabled = enabled;
88
- }
89
- /**
90
- * Set ambient light colors (skybox mode)
91
- */
92
- setAmbientLight(skyColor, groundColor, intensity = 1) {
93
- this.globalIllumination.skyColor = skyColor;
94
- this.globalIllumination.groundColor = groundColor;
95
- this.globalIllumination.skyIntensity = intensity;
96
- this.globalIllumination.groundIntensity = intensity * 0.5;
97
- }
98
- /**
99
- * Enable/disable screen-space ambient occlusion
100
- */
101
- setScreenSpaceAO(enabled, intensity = 1) {
102
- this.globalIllumination.screenSpaceAO = enabled;
103
- this.globalIllumination.aoIntensity = intensity;
104
- }
105
- /**
106
- * Create directional light (sun)
107
- */
108
- createDirectionalLight(direction, color, intensity = 1, castShadows = true) {
109
- const light = {
110
- type: "directional",
111
- name: `sun_${this.lightIdCounter}`,
112
- direction,
113
- color,
114
- intensity,
115
- shadow: castShadows ? {
116
- type: "soft",
117
- resolution: 2048,
118
- cascades: 4,
119
- softness: 1
120
- } : void 0,
121
- volumetric: true,
122
- priority: 100
123
- };
124
- return this.addLight(light);
125
- }
126
- /**
127
- * Create point light
128
- */
129
- createPointLight(position, color, intensity, range, castShadows = false) {
130
- const light = {
131
- type: "point",
132
- name: `point_${this.lightIdCounter}`,
133
- position,
134
- color,
135
- intensity,
136
- range,
137
- shadow: castShadows ? {
138
- type: "soft",
139
- resolution: 512,
140
- softness: 0.5
141
- } : void 0,
142
- priority: 50
143
- };
144
- return this.addLight(light);
145
- }
146
- /**
147
- * Create spot light
148
- */
149
- createSpotLight(position, direction, color, intensity, range, spotAngle = 45, castShadows = true) {
150
- const light = {
151
- type: "spot",
152
- name: `spot_${this.lightIdCounter}`,
153
- position,
154
- direction,
155
- color,
156
- intensity,
157
- range,
158
- spotAngle,
159
- innerSpotAngle: spotAngle * 0.5,
160
- shadow: castShadows ? {
161
- type: "soft",
162
- resolution: 1024,
163
- softness: 0.8
164
- } : void 0,
165
- priority: 75
166
- };
167
- return this.addLight(light);
168
- }
169
- /**
170
- * Create area light for soft lighting
171
- */
172
- createAreaLight(position, color, intensity, width, height) {
173
- const light = {
174
- type: "area",
175
- name: `area_${this.lightIdCounter}`,
176
- position,
177
- color,
178
- intensity,
179
- range: Math.max(width, height) * 2,
180
- priority: 25
181
- };
182
- return this.addLight(light);
183
- }
184
- /**
185
- * Get shadow-casting lights
186
- */
187
- getShadowCastingLights() {
188
- return Array.from(this.lights.values()).filter((l) => l.shadow && l.shadow.type !== "none");
189
- }
190
- /**
191
- * Get light count by type
192
- */
193
- getLightCount() {
194
- const counts = {
195
- directional: 0,
196
- point: 0,
197
- spot: 0,
198
- area: 0,
199
- probe: 0
200
- };
201
- for (const light of Array.from(this.lights.values())) {
202
- counts[light.type]++;
203
- }
204
- return counts;
205
- }
206
- /**
207
- * Estimate light impact for performance optimization
208
- */
209
- getPerformanceImpact() {
210
- const totalLights = this.lights.size;
211
- const shadowCasters = this.getShadowCastingLights().length;
212
- let estimatedGPUCost = "low";
213
- if (totalLights > 16 || shadowCasters > 4) {
214
- estimatedGPUCost = "high";
215
- } else if (totalLights > 8 || shadowCasters > 2) {
216
- estimatedGPUCost = "medium";
217
- }
218
- return {
219
- totalLights,
220
- shadowCasters,
221
- estimatedGPUCost
222
- };
223
- }
224
- /**
225
- * Get scene complexity info
226
- */
227
- getSceneInfo() {
228
- const counts = this.getLightCount();
229
- const impact = this.getPerformanceImpact();
230
- return `Lighting: ${counts.directional} dir, ${counts.point} point, ${counts.spot} spot | Shadows: ${impact.shadowCasters} | GPU: ${impact.estimatedGPUCost}`;
231
- }
232
- /**
233
- * Dispose and cleanup
234
- */
235
- dispose() {
236
- this.lights.clear();
237
- }
238
- };
239
- function createLightingTrait(config) {
240
- return new LightingTrait(config);
241
- }
242
- var LIGHTING_PRESETS = {
243
- /** Neutral studio lighting */
244
- studio: () => ({
245
- enabled: true,
246
- intensity: 1,
247
- skyColor: { r: 0.5, g: 0.5, b: 0.5 },
248
- skyIntensity: 0.5,
249
- groundColor: { r: 0.3, g: 0.3, b: 0.3 },
250
- groundIntensity: 0.3
251
- }),
252
- /** Bright outdoor lighting */
253
- outdoor: () => ({
254
- enabled: true,
255
- intensity: 1.2,
256
- skyColor: { r: 0.7, g: 0.85, b: 1 },
257
- skyIntensity: 1,
258
- groundColor: { r: 0.4, g: 0.4, b: 0.35 },
259
- groundIntensity: 0.6,
260
- indirectDiffuse: 1.2
261
- }),
262
- /** Dim interior lighting */
263
- interior: () => ({
264
- enabled: true,
265
- intensity: 0.6,
266
- skyColor: { r: 0.3, g: 0.3, b: 0.35 },
267
- skyIntensity: 0.4,
268
- groundColor: { r: 0.2, g: 0.2, b: 0.2 },
269
- groundIntensity: 0.2
270
- }),
271
- /** Night scene */
272
- night: () => ({
273
- enabled: true,
274
- intensity: 0.3,
275
- skyColor: { r: 0.01, g: 0.01, b: 0.02 },
276
- skyIntensity: 0.1,
277
- groundColor: { r: 0.02, g: 0.02, b: 0.02 },
278
- groundIntensity: 0.05,
279
- screenSpaceAO: false
280
- }),
281
- /** Sunset/golden hour */
282
- sunset: () => ({
283
- enabled: true,
284
- intensity: 1.1,
285
- skyColor: { r: 1, g: 0.7, b: 0.3 },
286
- skyIntensity: 1,
287
- groundColor: { r: 0.6, g: 0.4, b: 0.2 },
288
- groundIntensity: 0.8
289
- })
290
- };
291
- var lightingHandler = {
292
- name: "lighting",
293
- defaultConfig: {},
294
- onAttach(node, config, ctx) {
295
- const instance = new LightingTrait(config);
296
- node.__lighting_instance = instance;
297
- ctx.emit("lighting_attached", { node, config });
298
- },
299
- onDetach(node, _config, ctx) {
300
- const instance = node.__lighting_instance;
301
- if (instance) {
302
- if (typeof instance.onDetach === "function") instance.onDetach(node, ctx);
303
- else if (typeof instance.dispose === "function") instance.dispose();
304
- else if (typeof instance.cleanup === "function") instance.cleanup();
305
- }
306
- ctx.emit("lighting_detached", { node });
307
- delete node.__lighting_instance;
308
- },
309
- onEvent(node, _config, ctx, event) {
310
- const instance = node.__lighting_instance;
311
- if (!instance) return;
312
- if (typeof instance.onEvent === "function") instance.onEvent(event);
313
- else if (typeof instance.emit === "function" && event.type) instance.emit(event);
314
- if (event.type === "lighting_configure" && event.payload) {
315
- Object.assign(instance, event.payload);
316
- ctx.emit("lighting_configured", { node });
317
- }
318
- },
319
- onUpdate(node, _config, ctx, dt) {
320
- const instance = node.__lighting_instance;
321
- if (!instance) return;
322
- if (typeof instance.onUpdate === "function") instance.onUpdate(node, ctx, dt);
323
- }
324
- };
325
-
326
- // src/traits/MaterialTrait.ts
327
- var MaterialTrait = class {
328
- constructor(config) {
329
- this.textureCache = /* @__PURE__ */ new Map();
330
- this.material = {
331
- ...{ type: "pbr" },
332
- ...config
333
- };
334
- }
335
- /**
336
- * Get material properties
337
- */
338
- getMaterial() {
339
- return { ...this.material };
340
- }
341
- /**
342
- * Update material property
343
- */
344
- setProperty(key, value) {
345
- this.material[key] = value;
346
- }
347
- /**
348
- * Get PBR properties
349
- */
350
- getPBRProperties() {
351
- return this.material.pbr;
352
- }
353
- /**
354
- * Update PBR material
355
- */
356
- updatePBR(pbr) {
357
- if (!this.material.pbr) {
358
- this.material.pbr = {
359
- baseColor: { r: 1, g: 1, b: 1 },
360
- metallic: 0,
361
- roughness: 0.5
362
- };
363
- }
364
- this.material.pbr = { ...this.material.pbr, ...pbr };
365
- }
366
- /**
367
- * Add texture map
368
- */
369
- addTexture(texture) {
370
- if (!this.material.textures) {
371
- this.material.textures = [];
372
- }
373
- this.material.textures.push(texture);
374
- }
375
- /**
376
- * Get all textures
377
- */
378
- getTextures() {
379
- return [...this.material.textures || []];
380
- }
381
- /**
382
- * Clear texture cache (for memory optimization)
383
- */
384
- clearTextureCache() {
385
- this.textureCache.clear();
386
- }
387
- /**
388
- * Get shader code if custom
389
- */
390
- getCustomShader() {
391
- return this.material.customShader;
392
- }
393
- /**
394
- * Set custom shader
395
- */
396
- setCustomShader(shader) {
397
- this.material.customShader = shader;
398
- }
399
- /**
400
- * Get optimization hints
401
- */
402
- getOptimization() {
403
- return this.material.optimization;
404
- }
405
- /**
406
- * Enable/disable texture streaming
407
- */
408
- setTextureStreaming(enabled) {
409
- if (!this.material.optimization) {
410
- this.material.optimization = {};
411
- }
412
- this.material.optimization.streamTextures = enabled;
413
- }
414
- /**
415
- * Set texture compression
416
- */
417
- setCompression(compression) {
418
- if (!this.material.optimization) {
419
- this.material.optimization = {};
420
- }
421
- this.material.optimization.compression = compression;
422
- }
423
- /**
424
- * Enable material instancing for performance
425
- */
426
- setInstanced(instanced) {
427
- if (!this.material.optimization) {
428
- this.material.optimization = {};
429
- }
430
- this.material.optimization.instanced = instanced;
431
- }
432
- /**
433
- * Dispose and cleanup
434
- */
435
- dispose() {
436
- this.textureCache.clear();
437
- }
438
- };
439
- function createMaterialTrait(config) {
440
- return new MaterialTrait(config);
441
- }
442
- var MATERIAL_PRESETS = {
443
- /** Shiny metal */
444
- chrome: () => ({
445
- type: "pbr",
446
- pbr: {
447
- baseColor: { r: 0.77, g: 0.77, b: 0.77 },
448
- metallic: 1,
449
- roughness: 0.1
450
- }
451
- }),
452
- /** Rough plastic */
453
- plastic: () => ({
454
- type: "pbr",
455
- pbr: {
456
- baseColor: { r: 1, g: 1, b: 1 },
457
- metallic: 0,
458
- roughness: 0.8
459
- }
460
- }),
461
- /** Wood texture */
462
- wood: () => ({
463
- type: "pbr",
464
- pbr: {
465
- baseColor: { r: 0.6, g: 0.4, b: 0.2 },
466
- metallic: 0,
467
- roughness: 0.4
468
- }
469
- }),
470
- /** Glass */
471
- glass: () => ({
472
- type: "transparent",
473
- blendMode: "blend",
474
- pbr: {
475
- baseColor: { r: 1, g: 1, b: 1, a: 0.3 },
476
- metallic: 0,
477
- roughness: 0,
478
- ior: 1.5,
479
- transmission: 0.9
480
- }
481
- }),
482
- /** Emissive (glowing) */
483
- emissive: () => ({
484
- type: "pbr",
485
- pbr: {
486
- baseColor: { r: 0, g: 1, b: 0 },
487
- metallic: 0,
488
- roughness: 1,
489
- emission: {
490
- color: { r: 0, g: 1, b: 0 },
491
- intensity: 2
492
- }
493
- }
494
- }),
495
- /** Skin material */
496
- skin: () => ({
497
- type: "pbr",
498
- pbr: {
499
- baseColor: { r: 1, g: 0.8, b: 0.7 },
500
- metallic: 0,
501
- roughness: 0.5,
502
- ambientOcclusion: 0.8
503
- }
504
- })
505
- };
506
- var materialHandler = {
507
- name: "material",
508
- defaultConfig: {},
509
- onAttach(node, config, ctx) {
510
- const instance = new MaterialTrait(config);
511
- node.__material_instance = instance;
512
- ctx.emit("material_attached", { node, config });
513
- },
514
- onDetach(node, _config, ctx) {
515
- const instance = node.__material_instance;
516
- if (instance) {
517
- if (typeof instance.onDetach === "function") instance.onDetach(node, ctx);
518
- else if (typeof instance.dispose === "function") instance.dispose();
519
- else if (typeof instance.cleanup === "function") instance.cleanup();
520
- }
521
- ctx.emit("material_detached", { node });
522
- delete node.__material_instance;
523
- },
524
- onEvent(node, _config, ctx, event) {
525
- const instance = node.__material_instance;
526
- if (!instance) return;
527
- if (typeof instance.onEvent === "function") instance.onEvent(event);
528
- else if (typeof instance.emit === "function" && event.type) instance.emit(event);
529
- if (event.type === "material_configure" && event.payload) {
530
- Object.assign(instance, event.payload);
531
- ctx.emit("material_configured", { node });
532
- }
533
- },
534
- onUpdate(node, _config, ctx, dt) {
535
- const instance = node.__material_instance;
536
- if (!instance) return;
537
- if (typeof instance.onUpdate === "function") instance.onUpdate(node, ctx, dt);
538
- }
539
- };
540
-
541
- // src/traits/RenderingTrait.ts
542
- var RenderingTrait = class {
543
- constructor(config) {
544
- this.optimization = {
545
- lodStrategy: "automatic",
546
- culling: {
547
- mode: "back",
548
- frustum: true,
549
- occlusion: true
550
- },
551
- batching: {
552
- static: true,
553
- dynamic: true,
554
- instancing: true,
555
- maxInstanceCount: 1e3
556
- },
557
- textures: {
558
- streaming: true,
559
- compression: "auto",
560
- mipmaps: true,
561
- maxResolution: 2048
562
- },
563
- shaders: {
564
- simplifiedShaders: true,
565
- lodBias: 0
566
- },
567
- targetGPUTier: "high",
568
- adaptiveQuality: true,
569
- targetFrameRate: 60,
570
- ...config
571
- };
572
- }
573
- /**
574
- * Get rendering optimization config
575
- */
576
- getOptimization() {
577
- return JSON.parse(JSON.stringify(this.optimization));
578
- }
579
- /**
580
- * Update rendering configuration
581
- */
582
- updateOptimization(updates) {
583
- this.optimization = { ...this.optimization, ...updates };
584
- }
585
- /**
586
- * Setup LOD levels (3 levels is typical)
587
- */
588
- setupLODLevels(strategy = "automatic") {
589
- const levels = [
590
- {
591
- level: 0,
592
- screenRelativeSize: 0.5,
593
- polygonReduction: 1,
594
- textureScale: 1
595
- },
596
- {
597
- level: 1,
598
- screenRelativeSize: 0.25,
599
- polygonReduction: 0.6,
600
- disabledFeatures: ["specular"],
601
- textureScale: 0.5
602
- },
603
- {
604
- level: 2,
605
- screenRelativeSize: 0.1,
606
- polygonReduction: 0.3,
607
- disabledFeatures: ["specular", "normals"],
608
- textureScale: 0.25
609
- }
610
- ];
611
- this.optimization.lodStrategy = strategy;
612
- this.optimization.lodLevels = levels;
613
- }
614
- /**
615
- * Get LOD levels
616
- */
617
- getLODLevels() {
618
- return [...this.optimization.lodLevels || []];
619
- }
620
- /**
621
- * Configure culling
622
- */
623
- setCulling(config) {
624
- const defaultCulling = { mode: "back" };
625
- this.optimization.culling = {
626
- ...defaultCulling,
627
- ...this.optimization.culling,
628
- ...config
629
- };
630
- }
631
- /**
632
- * Enable frustum culling
633
- */
634
- setFrustumCulling(enabled) {
635
- if (!this.optimization.culling) {
636
- this.optimization.culling = { mode: "back" };
637
- }
638
- this.optimization.culling.frustum = enabled;
639
- }
640
- /**
641
- * Enable occlusion culling
642
- */
643
- setOcclusionCulling(enabled, distance) {
644
- if (!this.optimization.culling) {
645
- this.optimization.culling = { mode: "back" };
646
- }
647
- this.optimization.culling.occlusion = enabled;
648
- if (distance) {
649
- this.optimization.culling.occlusionDistance = distance;
650
- }
651
- }
652
- /**
653
- * Configure batching
654
- */
655
- setBatching(config) {
656
- this.optimization.batching = {
657
- ...this.optimization.batching,
658
- ...config
659
- };
660
- }
661
- /**
662
- * Enable GPU instancing
663
- */
664
- setInstancing(enabled, maxInstances) {
665
- if (!this.optimization.batching) {
666
- this.optimization.batching = {};
667
- }
668
- this.optimization.batching.instancing = enabled;
669
- if (maxInstances) {
670
- this.optimization.batching.maxInstanceCount = maxInstances;
671
- }
672
- }
673
- /**
674
- * Configure texture optimization
675
- */
676
- setTextureOptimization(config) {
677
- this.optimization.textures = {
678
- ...this.optimization.textures,
679
- ...config
680
- };
681
- }
682
- /**
683
- * Enable texture streaming
684
- */
685
- setTextureStreaming(enabled, budgetMB) {
686
- if (!this.optimization.textures) {
687
- this.optimization.textures = {};
688
- }
689
- this.optimization.textures.streaming = enabled;
690
- if (budgetMB) {
691
- this.optimization.textures.streamingBudget = budgetMB;
692
- }
693
- }
694
- /**
695
- * Set texture compression
696
- */
697
- setTextureCompression(compression) {
698
- if (!this.optimization.textures) {
699
- this.optimization.textures = {};
700
- }
701
- this.optimization.textures.compression = compression;
702
- }
703
- /**
704
- * Set max texture resolution
705
- */
706
- setMaxTextureResolution(resolution) {
707
- if (!this.optimization.textures) {
708
- this.optimization.textures = {};
709
- }
710
- this.optimization.textures.maxResolution = resolution;
711
- }
712
- /**
713
- * Configure shader optimization
714
- */
715
- setShaderOptimization(config) {
716
- this.optimization.shaders = {
717
- ...this.optimization.shaders,
718
- ...config
719
- };
720
- }
721
- /**
722
- * Set target GPU tier
723
- */
724
- setTargetGPUTier(tier) {
725
- this.optimization.targetGPUTier = tier;
726
- }
727
- /**
728
- * Enable adaptive quality (adjust based on frame rate)
729
- */
730
- setAdaptiveQuality(enabled, targetFrameRate) {
731
- this.optimization.adaptiveQuality = enabled;
732
- if (targetFrameRate) {
733
- this.optimization.targetFrameRate = targetFrameRate;
734
- }
735
- }
736
- /**
737
- * Set fixed timestep for VR/AR
738
- */
739
- setFixedTimestep(timestep) {
740
- this.optimization.fixedTimestep = timestep;
741
- }
742
- /**
743
- * Get rendering preset for quality level
744
- */
745
- getPresetForQuality(quality) {
746
- const presets = {
747
- low: {
748
- targetGPUTier: "low",
749
- lodStrategy: "automatic",
750
- culling: { mode: "back", frustum: true, occlusion: false },
751
- batching: { instancing: true, maxInstanceCount: 500 },
752
- textures: {
753
- compression: "astc",
754
- maxResolution: 512,
755
- streaming: true,
756
- streamingBudget: 128
757
- },
758
- adaptiveQuality: true,
759
- targetFrameRate: 30
760
- },
761
- medium: {
762
- targetGPUTier: "medium",
763
- lodStrategy: "automatic",
764
- culling: { mode: "back", frustum: true, occlusion: true },
765
- batching: { instancing: true, maxInstanceCount: 1e3 },
766
- textures: {
767
- compression: "basis",
768
- maxResolution: 1024,
769
- streaming: true,
770
- streamingBudget: 256
771
- },
772
- adaptiveQuality: true,
773
- targetFrameRate: 60
774
- },
775
- high: {
776
- targetGPUTier: "high",
777
- lodStrategy: "automatic",
778
- culling: { mode: "back", frustum: true, occlusion: true },
779
- batching: { instancing: true, maxInstanceCount: 2e3 },
780
- textures: {
781
- compression: "dxt",
782
- maxResolution: 2048,
783
- streaming: true,
784
- streamingBudget: 512
785
- },
786
- adaptiveQuality: false,
787
- targetFrameRate: 60
788
- },
789
- ultra: {
790
- targetGPUTier: "ultra",
791
- lodStrategy: "manual",
792
- culling: {
793
- mode: "back",
794
- frustum: true,
795
- occlusion: true,
796
- hierarchicalZ: true
797
- },
798
- batching: { instancing: true, maxInstanceCount: 5e3 },
799
- textures: {
800
- compression: "none",
801
- maxResolution: 4096,
802
- virtualTexturing: true,
803
- streaming: true,
804
- streamingBudget: 1024
805
- },
806
- adaptiveQuality: false,
807
- targetFrameRate: 120
808
- }
809
- };
810
- return { ...this.optimization, ...presets[quality] };
811
- }
812
- /**
813
- * Apply quality preset
814
- */
815
- applyQualityPreset(quality) {
816
- const preset = this.getPresetForQuality(quality);
817
- this.optimization = preset;
818
- }
819
- /**
820
- * Estimate GPU memory usage
821
- */
822
- estimateGPUMemory() {
823
- let textureMemory = 0;
824
- let vertexBuffers = 0;
825
- const maxRes = this.optimization.textures?.maxResolution || 2048;
826
- textureMemory = maxRes * maxRes * 4 / (1024 * 1024);
827
- const instanceCount = this.optimization.batching?.maxInstanceCount || 1e3;
828
- const verticesPerMesh = 1e4;
829
- vertexBuffers = verticesPerMesh * 36 * instanceCount / (1024 * 1024) * 0.1;
830
- return {
831
- textureMemory: Math.round(textureMemory),
832
- vertexBuffers: Math.max(1, Math.round(vertexBuffers)),
833
- // At least 1MB
834
- estimatedTotal: Math.round(textureMemory + Math.max(1, vertexBuffers))
835
- };
836
- }
837
- /**
838
- * Get rendering statistics/info
839
- */
840
- getInfo() {
841
- const tier = this.optimization.targetGPUTier;
842
- const lod = this.optimization.lodStrategy;
843
- const culling = this.optimization.culling?.mode;
844
- const instancing = this.optimization.batching?.instancing ? "yes" : "no";
845
- const memory = this.estimateGPUMemory();
846
- return `Rendering: tier=${tier} | LOD=${lod} | culling=${culling} | instancing=${instancing} | memory=${memory.estimatedTotal}MB`;
847
- }
848
- /**
849
- * Optimize for VR/AR (fixed timestep, fast culling)
850
- */
851
- optimizeForVRAR(targetFPS = 90) {
852
- this.optimization.fixedTimestep = 1 / targetFPS;
853
- this.optimization.targetFrameRate = targetFPS;
854
- this.setOcclusionCulling(true, 50);
855
- this.setInstancing(true, 5e3);
856
- this.setAdaptiveQuality(true, targetFPS);
857
- }
858
- /**
859
- * Optimize for mobile (lower resources)
860
- */
861
- optimizeForMobile() {
862
- this.applyQualityPreset("low");
863
- this.setTextureCompression("astc");
864
- this.setInstancing(true, 256);
865
- }
866
- /**
867
- * Optimize for desktop (higher resources)
868
- */
869
- optimizeForDesktop() {
870
- this.applyQualityPreset("ultra");
871
- this.setTextureCompression("none");
872
- this.setInstancing(true, 5e3);
873
- }
874
- /**
875
- * Dispose and cleanup
876
- */
877
- dispose() {
878
- }
879
- };
880
- function createRenderingTrait(config) {
881
- return new RenderingTrait(config);
882
- }
883
- var renderingHandler = {
884
- name: "rendering",
885
- defaultConfig: {},
886
- onAttach(node, config, ctx) {
887
- const instance = new RenderingTrait(config);
888
- node.__rendering_instance = instance;
889
- ctx.emit("rendering_attached", { node, config });
890
- },
891
- onDetach(node, _config, ctx) {
892
- const instance = node.__rendering_instance;
893
- if (instance) {
894
- if (typeof instance.onDetach === "function") instance.onDetach(node, ctx);
895
- else if (typeof instance.dispose === "function") instance.dispose();
896
- else if (typeof instance.cleanup === "function") instance.cleanup();
897
- }
898
- ctx.emit("rendering_detached", { node });
899
- delete node.__rendering_instance;
900
- },
901
- onEvent(node, _config, ctx, event) {
902
- const instance = node.__rendering_instance;
903
- if (!instance) return;
904
- if (typeof instance.onEvent === "function") instance.onEvent(event);
905
- else if (typeof instance.emit === "function" && event.type) instance.emit(event);
906
- if (event.type === "rendering_configure" && event.payload) {
907
- Object.assign(instance, event.payload);
908
- ctx.emit("rendering_configured", { node });
909
- }
910
- },
911
- onUpdate(node, _config, ctx, dt) {
912
- const instance = node.__rendering_instance;
913
- if (!instance) return;
914
- if (typeof instance.onUpdate === "function") instance.onUpdate(node, ctx, dt);
915
- }
916
- };
917
-
918
- // src/traits/ShaderTrait.ts
919
- var SHADER_CHUNKS = {
920
- /** Common noise functions */
921
- noise: `
922
- // Simplex 2D noise
923
- vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
924
- vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
925
- vec3 permute(vec3 x) { return mod289(((x*34.0)+1.0)*x); }
926
-
927
- float snoise(vec2 v) {
928
- const vec4 C = vec4(0.211324865405187, 0.366025403784439,
929
- -0.577350269189626, 0.024390243902439);
930
- vec2 i = floor(v + dot(v, C.yy));
931
- vec2 x0 = v - i + dot(i, C.xx);
932
- vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
933
- vec4 x12 = x0.xyxy + C.xxzz;
934
- x12.xy -= i1;
935
- i = mod289(i);
936
- vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));
937
- vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
938
- m = m*m;
939
- m = m*m;
940
- vec3 x = 2.0 * fract(p * C.www) - 1.0;
941
- vec3 h = abs(x) - 0.5;
942
- vec3 ox = floor(x + 0.5);
943
- vec3 a0 = x - ox;
944
- m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h);
945
- vec3 g;
946
- g.x = a0.x * x0.x + h.x * x0.y;
947
- g.yz = a0.yz * x12.xz + h.yz * x12.yw;
948
- return 130.0 * dot(m, g);
949
- }
950
- `,
951
- /** Hologram effect */
952
- hologram: `
953
- // Hologram scanline effect
954
- float hologramScanline(vec2 uv, float time, float density) {
955
- return sin(uv.y * density + time * 2.0) * 0.5 + 0.5;
956
- }
957
-
958
- // Hologram flicker
959
- float hologramFlicker(float time) {
960
- return 0.9 + 0.1 * sin(time * 20.0) * sin(time * 13.0);
961
- }
962
-
963
- // Hologram edge glow
964
- float hologramEdge(vec3 normal, vec3 viewDir) {
965
- return pow(1.0 - abs(dot(normal, viewDir)), 2.0);
966
- }
967
- `,
968
- /** Fresnel effect */
969
- fresnel: `
970
- // Basic Fresnel
971
- float fresnel(vec3 normal, vec3 viewDir, float power) {
972
- return pow(1.0 - abs(dot(normal, viewDir)), power);
973
- }
974
-
975
- // Schlick's approximation
976
- float fresnelSchlick(float cosTheta, float F0) {
977
- return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
978
- }
979
- `,
980
- /** PBR lighting */
981
- pbr: `
982
- // Distribution function (GGX/Trowbridge-Reitz)
983
- float distributionGGX(vec3 N, vec3 H, float roughness) {
984
- float a = roughness * roughness;
985
- float a2 = a * a;
986
- float NdotH = max(dot(N, H), 0.0);
987
- float NdotH2 = NdotH * NdotH;
988
- float num = a2;
989
- float denom = (NdotH2 * (a2 - 1.0) + 1.0);
990
- denom = 3.14159265 * denom * denom;
991
- return num / denom;
992
- }
993
-
994
- // Geometry function (Schlick-GGX)
995
- float geometrySchlickGGX(float NdotV, float roughness) {
996
- float r = (roughness + 1.0);
997
- float k = (r * r) / 8.0;
998
- float num = NdotV;
999
- float denom = NdotV * (1.0 - k) + k;
1000
- return num / denom;
1001
- }
1002
-
1003
- // Smith's geometry function
1004
- float geometrySmith(vec3 N, vec3 V, vec3 L, float roughness) {
1005
- float NdotV = max(dot(N, V), 0.0);
1006
- float NdotL = max(dot(N, L), 0.0);
1007
- float ggx2 = geometrySchlickGGX(NdotV, roughness);
1008
- float ggx1 = geometrySchlickGGX(NdotL, roughness);
1009
- return ggx1 * ggx2;
1010
- }
1011
- `,
1012
- /** UV utilities */
1013
- uv: `
1014
- // Rotate UV
1015
- vec2 rotateUV(vec2 uv, float angle) {
1016
- float c = cos(angle);
1017
- float s = sin(angle);
1018
- return vec2(c * uv.x - s * uv.y, s * uv.x + c * uv.y);
1019
- }
1020
-
1021
- // Tile UV
1022
- vec2 tileUV(vec2 uv, vec2 scale) {
1023
- return fract(uv * scale);
1024
- }
1025
-
1026
- // Parallax mapping
1027
- vec2 parallaxUV(vec2 uv, vec3 viewDir, sampler2D heightMap, float scale) {
1028
- float height = texture2D(heightMap, uv).r;
1029
- vec2 p = viewDir.xy / viewDir.z * (height * scale);
1030
- return uv - p;
1031
- }
1032
- `
1033
- };
1034
- var ShaderTrait = class {
1035
- constructor(config) {
1036
- this.uniformValues = /* @__PURE__ */ new Map();
1037
- this.config = {
1038
- ...config,
1039
- source: {
1040
- language: config.source?.language || "glsl",
1041
- vertex: config.source?.vertex || "",
1042
- fragment: config.source?.fragment || "",
1043
- geometry: config.source?.geometry,
1044
- tessellationControl: config.source?.tessellationControl,
1045
- tessellationEvaluation: config.source?.tessellationEvaluation,
1046
- compute: config.source?.compute
1047
- }
1048
- };
1049
- if (config.uniforms) {
1050
- for (const [name, uniform] of Object.entries(config.uniforms)) {
1051
- this.uniformValues.set(name, uniform.value);
1052
- }
1053
- }
1054
- }
1055
- /**
1056
- * Get shader configuration
1057
- */
1058
- getConfig() {
1059
- return { ...this.config };
1060
- }
1061
- /**
1062
- * Get vertex shader source with includes
1063
- */
1064
- getVertexSource() {
1065
- return this.assembleShaderSource("vertex");
1066
- }
1067
- /**
1068
- * Get fragment shader source with includes
1069
- */
1070
- getFragmentSource() {
1071
- return this.assembleShaderSource("fragment");
1072
- }
1073
- /**
1074
- * Assemble shader source with includes and uniforms
1075
- */
1076
- assembleShaderSource(stage) {
1077
- const source = this.config.source ? this.config.source[stage] : void 0;
1078
- if (!source) return "";
1079
- let assembled = "";
1080
- if (this.config.source?.language === "glsl") {
1081
- assembled += "precision highp float;\n\n";
1082
- }
1083
- if (this.config.uniforms) {
1084
- for (const [name, uniform] of Object.entries(this.config.uniforms)) {
1085
- assembled += `uniform ${this.getGLSLType(uniform.type)} ${name};
1086
- `;
1087
- }
1088
- assembled += "\n";
1089
- }
1090
- if (this.config.includes) {
1091
- for (const include of this.config.includes) {
1092
- const chunk = SHADER_CHUNKS[include.path];
1093
- if (chunk) {
1094
- assembled += `// Include: ${include.path}
1095
- ${chunk}
1096
- `;
1097
- }
1098
- }
1099
- }
1100
- assembled += source;
1101
- return assembled;
1102
- }
1103
- /**
1104
- * Convert uniform type to GLSL type
1105
- */
1106
- getGLSLType(type) {
1107
- const typeMap = {
1108
- float: "float",
1109
- int: "int",
1110
- bool: "bool",
1111
- vec2: "vec2",
1112
- vec3: "vec3",
1113
- vec4: "vec4",
1114
- mat2: "mat2",
1115
- mat3: "mat3",
1116
- mat4: "mat4",
1117
- sampler2D: "sampler2D",
1118
- samplerCube: "samplerCube"
1119
- };
1120
- return typeMap[type] || "float";
1121
- }
1122
- /**
1123
- * Set uniform value
1124
- */
1125
- setUniform(name, value) {
1126
- this.uniformValues.set(name, value);
1127
- }
1128
- /**
1129
- * Get uniform value
1130
- */
1131
- getUniform(name) {
1132
- return this.uniformValues.get(name);
1133
- }
1134
- /**
1135
- * Get all uniform values
1136
- */
1137
- getUniforms() {
1138
- return new Map(this.uniformValues);
1139
- }
1140
- /**
1141
- * Validate shader syntax
1142
- */
1143
- validate() {
1144
- const errors = [];
1145
- const warnings = [];
1146
- if (this.config.source?.vertex) {
1147
- const vertexErrors = this.validateShaderSyntax(this.config.source.vertex, "vertex");
1148
- errors.push(...vertexErrors);
1149
- }
1150
- if (this.config.source?.fragment) {
1151
- const fragmentErrors = this.validateShaderSyntax(this.config.source.fragment, "fragment");
1152
- errors.push(...fragmentErrors);
1153
- }
1154
- if (this.config.source?.vertex && !this.config.source.vertex.includes("void main")) {
1155
- errors.push({
1156
- stage: "vertex",
1157
- line: 1,
1158
- message: "Vertex shader must contain a main() function",
1159
- code: "E001"
1160
- });
1161
- }
1162
- if (this.config.source?.fragment && !this.config.source.fragment.includes("void main")) {
1163
- errors.push({
1164
- stage: "fragment",
1165
- line: 1,
1166
- message: "Fragment shader must contain a main() function",
1167
- code: "E002"
1168
- });
1169
- }
1170
- this.compilationResult = {
1171
- success: errors.length === 0,
1172
- errors,
1173
- warnings
1174
- };
1175
- return this.compilationResult;
1176
- }
1177
- /**
1178
- * Basic shader syntax validation
1179
- */
1180
- validateShaderSyntax(source, stage) {
1181
- const errors = [];
1182
- const lines = source.split("\n");
1183
- let braceCount = 0;
1184
- for (let i = 0; i < lines.length; i++) {
1185
- const line = lines[i];
1186
- braceCount += (line.match(/{/g) || []).length;
1187
- braceCount -= (line.match(/}/g) || []).length;
1188
- }
1189
- if (braceCount !== 0) {
1190
- errors.push({
1191
- stage,
1192
- line: lines.length,
1193
- message: `Unbalanced braces in ${stage} shader`,
1194
- code: "E003"
1195
- });
1196
- }
1197
- let parenCount = 0;
1198
- for (let i = 0; i < lines.length; i++) {
1199
- const line = lines[i];
1200
- parenCount += (line.match(/\(/g) || []).length;
1201
- parenCount -= (line.match(/\)/g) || []).length;
1202
- }
1203
- if (parenCount !== 0) {
1204
- errors.push({
1205
- stage,
1206
- line: lines.length,
1207
- message: `Unbalanced parentheses in ${stage} shader`,
1208
- code: "E004"
1209
- });
1210
- }
1211
- return errors;
1212
- }
1213
- /**
1214
- * Compile shader to target platform
1215
- */
1216
- compile(options) {
1217
- const validation = this.validate();
1218
- if (!validation.success) {
1219
- return validation;
1220
- }
1221
- let vertexSource = this.getVertexSource();
1222
- let fragmentSource = this.getFragmentSource();
1223
- if (options?.defines) {
1224
- for (const [key, value] of Object.entries(options.defines)) {
1225
- const define = `#define ${key} ${value}
1226
- `;
1227
- vertexSource = define + vertexSource;
1228
- fragmentSource = define + fragmentSource;
1229
- }
1230
- }
1231
- return {
1232
- success: true,
1233
- errors: [],
1234
- warnings: [],
1235
- compiledCode: {
1236
- vertex: vertexSource,
1237
- fragment: fragmentSource
1238
- }
1239
- };
1240
- }
1241
- /**
1242
- * Create Three.js ShaderMaterial config
1243
- */
1244
- toThreeJSConfig() {
1245
- const uniformsObj = {};
1246
- for (const [name, value] of this.uniformValues) {
1247
- uniformsObj[name] = { value };
1248
- }
1249
- return {
1250
- vertexShader: this.getVertexSource(),
1251
- fragmentShader: this.getFragmentSource(),
1252
- uniforms: uniformsObj,
1253
- transparent: this.config.blendMode !== "opaque",
1254
- depthTest: this.config.depthTest ?? true,
1255
- depthWrite: this.config.depthWrite ?? true,
1256
- side: this.getCullSide()
1257
- };
1258
- }
1259
- getCullSide() {
1260
- const THREE_FrontSide = 0;
1261
- const THREE_BackSide = 1;
1262
- const THREE_DoubleSide = 2;
1263
- switch (this.config.cullFace) {
1264
- case "front":
1265
- return THREE_BackSide;
1266
- case "back":
1267
- return THREE_FrontSide;
1268
- case "none":
1269
- return THREE_DoubleSide;
1270
- default:
1271
- return THREE_FrontSide;
1272
- }
1273
- }
1274
- };
1275
- var SHADER_PRESETS = {
1276
- /** Hologram effect shader */
1277
- hologram: {
1278
- name: "hologram",
1279
- source: {
1280
- language: "glsl",
1281
- vertex: `
1282
- varying vec2 vUv;
1283
- varying vec3 vNormal;
1284
- varying vec3 vViewPosition;
1285
-
1286
- void main() {
1287
- vUv = uv;
1288
- vNormal = normalize(normalMatrix * normal);
1289
- vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
1290
- vViewPosition = -mvPosition.xyz;
1291
- gl_Position = projectionMatrix * mvPosition;
1292
- }
1293
- `,
1294
- fragment: `
1295
- uniform float time;
1296
- uniform vec3 color;
1297
- uniform float opacity;
1298
- uniform float scanlineIntensity;
1299
- uniform float flickerIntensity;
1300
-
1301
- varying vec2 vUv;
1302
- varying vec3 vNormal;
1303
- varying vec3 vViewPosition;
1304
-
1305
- void main() {
1306
- // Fresnel edge glow
1307
- vec3 viewDir = normalize(vViewPosition);
1308
- float fresnel = pow(1.0 - abs(dot(vNormal, viewDir)), 2.0);
1309
-
1310
- // Scanlines
1311
- float scanline = sin(vUv.y * 100.0 + time * 2.0) * scanlineIntensity;
1312
-
1313
- // Flicker
1314
- float flicker = 0.9 + flickerIntensity * sin(time * 20.0) * sin(time * 13.0);
1315
-
1316
- // Combine
1317
- float alpha = (opacity + fresnel * 0.3 + scanline) * flicker;
1318
- vec3 finalColor = color + fresnel * 0.5;
1319
-
1320
- gl_FragColor = vec4(finalColor, alpha);
1321
- }
1322
- `
1323
- },
1324
- uniforms: {
1325
- time: { type: "float", value: 0 },
1326
- color: { type: "vec3", value: [0, 1, 1] },
1327
- opacity: { type: "float", value: 0.5, min: 0, max: 1 },
1328
- scanlineIntensity: { type: "float", value: 0.1, min: 0, max: 0.5 },
1329
- flickerIntensity: { type: "float", value: 0.1, min: 0, max: 0.3 }
1330
- },
1331
- blendMode: "blend",
1332
- depthWrite: false,
1333
- cullFace: "none"
1334
- },
1335
- /** Force field shader */
1336
- forceField: {
1337
- name: "forceField",
1338
- source: {
1339
- language: "glsl",
1340
- vertex: `
1341
- varying vec2 vUv;
1342
- varying vec3 vNormal;
1343
- varying vec3 vWorldPosition;
1344
-
1345
- void main() {
1346
- vUv = uv;
1347
- vNormal = normalize(normalMatrix * normal);
1348
- vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;
1349
- gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
1350
- }
1351
- `,
1352
- fragment: `
1353
- uniform float time;
1354
- uniform vec3 color;
1355
- uniform float pulseSpeed;
1356
- uniform float hexScale;
1357
-
1358
- varying vec2 vUv;
1359
- varying vec3 vNormal;
1360
- varying vec3 vWorldPosition;
1361
-
1362
- float hexPattern(vec2 p) {
1363
- vec2 q = vec2(p.x * 2.0 * 0.5773503, p.y + p.x * 0.5773503);
1364
- vec2 pi = floor(q);
1365
- vec2 pf = fract(q);
1366
- float v = mod(pi.x + pi.y, 3.0);
1367
- float ca = step(1.0, v);
1368
- float cb = step(2.0, v);
1369
- vec2 ma = step(pf.xy, pf.yx);
1370
- float e = dot(ma, 1.0 - pf.yx + ca * (pf.x + pf.y - 1.0) + cb * (pf.yx - 2.0 * pf.xy));
1371
- return e;
1372
- }
1373
-
1374
- void main() {
1375
- float hex = hexPattern(vUv * hexScale);
1376
- float pulse = sin(time * pulseSpeed) * 0.5 + 0.5;
1377
- float alpha = hex * (0.3 + pulse * 0.2);
1378
- gl_FragColor = vec4(color, alpha);
1379
- }
1380
- `
1381
- },
1382
- uniforms: {
1383
- time: { type: "float", value: 0 },
1384
- color: { type: "vec3", value: [0.2, 0.5, 1] },
1385
- pulseSpeed: { type: "float", value: 2, min: 0.5, max: 5 },
1386
- hexScale: { type: "float", value: 10, min: 5, max: 50 }
1387
- },
1388
- blendMode: "additive",
1389
- depthWrite: false,
1390
- cullFace: "none"
1391
- },
1392
- /** Dissolve effect shader */
1393
- dissolve: {
1394
- name: "dissolve",
1395
- source: {
1396
- language: "glsl",
1397
- vertex: `
1398
- varying vec2 vUv;
1399
- varying vec3 vPosition;
1400
-
1401
- void main() {
1402
- vUv = uv;
1403
- vPosition = position;
1404
- gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
1405
- }
1406
- `,
1407
- fragment: `
1408
- uniform float progress;
1409
- uniform vec3 edgeColor;
1410
- uniform float edgeWidth;
1411
- uniform sampler2D noiseTexture;
1412
-
1413
- varying vec2 vUv;
1414
- varying vec3 vPosition;
1415
-
1416
- void main() {
1417
- float noise = texture2D(noiseTexture, vUv).r;
1418
- float diff = noise - progress;
1419
-
1420
- if (diff < 0.0) discard;
1421
-
1422
- float edge = smoothstep(0.0, edgeWidth, diff);
1423
- vec3 color = mix(edgeColor, vec3(1.0), edge);
1424
-
1425
- gl_FragColor = vec4(color, 1.0);
1426
- }
1427
- `
1428
- },
1429
- uniforms: {
1430
- progress: { type: "float", value: 0, min: 0, max: 1 },
1431
- edgeColor: { type: "vec3", value: [1, 0.5, 0] },
1432
- edgeWidth: { type: "float", value: 0.1, min: 0.01, max: 0.5 },
1433
- noiseTexture: { type: "sampler2D", value: "" }
1434
- },
1435
- blendMode: "opaque"
1436
- }
1437
- };
1438
- function createShaderTrait(config) {
1439
- return new ShaderTrait({
1440
- name: "custom",
1441
- source: {
1442
- language: "glsl",
1443
- vertex: "",
1444
- fragment: ""
1445
- },
1446
- uniforms: {},
1447
- blendMode: "opaque",
1448
- ...config
1449
- });
1450
- }
1451
- var shaderHandler = {
1452
- name: "shader",
1453
- defaultConfig: {},
1454
- onAttach(node, config, ctx) {
1455
- const instance = new ShaderTrait(config);
1456
- node.__shader_instance = instance;
1457
- ctx.emit("shader_attached", { node, config });
1458
- },
1459
- onDetach(node, _config, ctx) {
1460
- const instance = node.__shader_instance;
1461
- if (instance) {
1462
- if (typeof instance.onDetach === "function") instance.onDetach(node, ctx);
1463
- else if (typeof instance.dispose === "function") instance.dispose();
1464
- else if (typeof instance.cleanup === "function") instance.cleanup();
1465
- }
1466
- ctx.emit("shader_detached", { node });
1467
- delete node.__shader_instance;
1468
- },
1469
- onEvent(node, _config, ctx, event) {
1470
- const instance = node.__shader_instance;
1471
- if (!instance) return;
1472
- if (typeof instance.onEvent === "function") instance.onEvent(event);
1473
- else if (typeof instance.emit === "function" && event.type) instance.emit(event);
1474
- if (event.type === "shader_configure" && event.payload) {
1475
- Object.assign(instance, event.payload);
1476
- ctx.emit("shader_configured", { node });
1477
- }
1478
- },
1479
- onUpdate(node, _config, ctx, dt) {
1480
- const instance = node.__shader_instance;
1481
- if (!instance) return;
1482
- if (typeof instance.onUpdate === "function") instance.onUpdate(node, ctx, dt);
1483
- }
1484
- };
1485
-
1486
- export { LIGHTING_PRESETS, LightingTrait, MATERIAL_PRESETS, MaterialTrait, RenderingTrait, SHADER_CHUNKS, SHADER_PRESETS, ShaderTrait, createLightingTrait, createMaterialTrait, createRenderingTrait, createShaderTrait, lightingHandler, materialHandler, renderingHandler, shaderHandler };
1487
- //# sourceMappingURL=chunk-F4IULT7N.js.map
1488
- //# sourceMappingURL=chunk-F4IULT7N.js.map