@vib3code/sdk 2.0.1

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 (258) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +34 -0
  3. package/DOCS/CI_TESTING.md +38 -0
  4. package/DOCS/CLI_ONBOARDING.md +75 -0
  5. package/DOCS/CONTROL_REFERENCE.md +64 -0
  6. package/DOCS/DEV_TRACK_ANALYSIS.md +77 -0
  7. package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +42 -0
  8. package/DOCS/DEV_TRACK_SESSION_2026-01-31.md +220 -0
  9. package/DOCS/ENV_SETUP.md +189 -0
  10. package/DOCS/EXPORT_FORMATS.md +417 -0
  11. package/DOCS/GPU_DISPOSAL_GUIDE.md +21 -0
  12. package/DOCS/LICENSING_TIERS.md +275 -0
  13. package/DOCS/MASTER_PLAN_2026-01-31.md +570 -0
  14. package/DOCS/OBS_SETUP_GUIDE.md +98 -0
  15. package/DOCS/PROJECT_SETUP.md +66 -0
  16. package/DOCS/RENDERER_LIFECYCLE.md +40 -0
  17. package/DOCS/REPO_MANIFEST.md +121 -0
  18. package/DOCS/SESSION_014_PLAN.md +195 -0
  19. package/DOCS/SESSION_LOG_2026-01-07.md +56 -0
  20. package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +72 -0
  21. package/DOCS/SYSTEM_AUDIT_2026-01-30.md +738 -0
  22. package/DOCS/SYSTEM_INVENTORY.md +520 -0
  23. package/DOCS/TELEMETRY_EXPORTS.md +34 -0
  24. package/DOCS/WEBGPU_STATUS.md +38 -0
  25. package/DOCS/XR_BENCHMARKS.md +608 -0
  26. package/LICENSE +21 -0
  27. package/README.md +426 -0
  28. package/docs/.nojekyll +0 -0
  29. package/docs/01-dissolution_of_euclidean_hegemony.html +346 -0
  30. package/docs/02-hyperspatial_ego_death.html +346 -0
  31. package/docs/03-post_cartesian_sublime.html +346 -0
  32. package/docs/04-crystalline_void_meditation.html +346 -0
  33. package/docs/05-quantum_decoherence_ballet.html +346 -0
  34. package/docs/06-dissolution_of_euclidean_hegemony.html +346 -0
  35. package/docs/07-hyperspatial_ego_death.html +346 -0
  36. package/docs/08-post_cartesian_sublime.html +346 -0
  37. package/docs/09-crystalline_void_meditation.html +346 -0
  38. package/docs/10-quantum_decoherence_ballet.html +346 -0
  39. package/docs/11-dissolution_of_euclidean_hegemony.html +346 -0
  40. package/docs/12-hyperspatial_ego_death.html +346 -0
  41. package/docs/13-post_cartesian_sublime.html +346 -0
  42. package/docs/index.html +794 -0
  43. package/docs/test-hub.html +441 -0
  44. package/docs/url-state.js +102 -0
  45. package/docs/vib3-exports/01-quantum-quantum-tetrahedron-lattice.html +489 -0
  46. package/docs/vib3-exports/02-quantum-quantum-hypersphere-matrix.html +489 -0
  47. package/docs/vib3-exports/03-quantum-quantum-hypertetra-fractal.html +489 -0
  48. package/docs/vib3-exports/04-faceted-faceted-crystal-structure.html +407 -0
  49. package/docs/vib3-exports/05-faceted-faceted-klein-bottle.html +407 -0
  50. package/docs/vib3-exports/06-faceted-faceted-hypertetra-torus.html +407 -0
  51. package/docs/vib3-exports/07-holographic-holographic-wave-field.html +457 -0
  52. package/docs/vib3-exports/08-holographic-holographic-hypersphere-sphere.html +457 -0
  53. package/docs/vib3-exports/09-holographic-holographic-hypertetra-crystal.html +457 -0
  54. package/docs/vib3-exports/index.html +238 -0
  55. package/docs/webgpu-live.html +702 -0
  56. package/package.json +367 -0
  57. package/src/advanced/AIPresetGenerator.js +777 -0
  58. package/src/advanced/MIDIController.js +703 -0
  59. package/src/advanced/OffscreenWorker.js +1051 -0
  60. package/src/advanced/WebGPUCompute.js +1051 -0
  61. package/src/advanced/WebXRRenderer.js +680 -0
  62. package/src/agent/cli/AgentCLI.js +615 -0
  63. package/src/agent/cli/index.js +14 -0
  64. package/src/agent/index.js +73 -0
  65. package/src/agent/mcp/MCPServer.js +950 -0
  66. package/src/agent/mcp/index.js +9 -0
  67. package/src/agent/mcp/tools.js +548 -0
  68. package/src/agent/telemetry/EventStream.js +669 -0
  69. package/src/agent/telemetry/Instrumentation.js +618 -0
  70. package/src/agent/telemetry/TelemetryExporters.js +427 -0
  71. package/src/agent/telemetry/TelemetryService.js +464 -0
  72. package/src/agent/telemetry/index.js +52 -0
  73. package/src/benchmarks/BenchmarkRunner.js +381 -0
  74. package/src/benchmarks/MetricsCollector.js +299 -0
  75. package/src/benchmarks/index.js +9 -0
  76. package/src/benchmarks/scenes.js +259 -0
  77. package/src/cli/index.js +675 -0
  78. package/src/config/ApiConfig.js +88 -0
  79. package/src/core/CanvasManager.js +217 -0
  80. package/src/core/ErrorReporter.js +117 -0
  81. package/src/core/ParameterMapper.js +333 -0
  82. package/src/core/Parameters.js +396 -0
  83. package/src/core/RendererContracts.js +200 -0
  84. package/src/core/UnifiedResourceManager.js +370 -0
  85. package/src/core/VIB3Engine.js +636 -0
  86. package/src/core/renderers/FacetedRendererAdapter.js +32 -0
  87. package/src/core/renderers/HolographicRendererAdapter.js +29 -0
  88. package/src/core/renderers/QuantumRendererAdapter.js +29 -0
  89. package/src/core/renderers/RendererLifecycleManager.js +63 -0
  90. package/src/creative/ColorPresetsSystem.js +980 -0
  91. package/src/creative/ParameterTimeline.js +1061 -0
  92. package/src/creative/PostProcessingPipeline.js +1113 -0
  93. package/src/creative/TransitionAnimator.js +683 -0
  94. package/src/export/CSSExporter.js +226 -0
  95. package/src/export/CardGeneratorBase.js +279 -0
  96. package/src/export/ExportManager.js +580 -0
  97. package/src/export/FacetedCardGenerator.js +279 -0
  98. package/src/export/HolographicCardGenerator.js +543 -0
  99. package/src/export/LottieExporter.js +552 -0
  100. package/src/export/QuantumCardGenerator.js +315 -0
  101. package/src/export/SVGExporter.js +519 -0
  102. package/src/export/ShaderExporter.js +903 -0
  103. package/src/export/TradingCardGenerator.js +3055 -0
  104. package/src/export/TradingCardManager.js +181 -0
  105. package/src/export/VIB3PackageExporter.js +559 -0
  106. package/src/export/index.js +14 -0
  107. package/src/export/systems/TradingCardSystemFaceted.js +494 -0
  108. package/src/export/systems/TradingCardSystemHolographic.js +452 -0
  109. package/src/export/systems/TradingCardSystemQuantum.js +411 -0
  110. package/src/faceted/FacetedSystem.js +963 -0
  111. package/src/features/CollectionManager.js +433 -0
  112. package/src/gallery/CollectionManager.js +240 -0
  113. package/src/gallery/GallerySystem.js +485 -0
  114. package/src/geometry/GeometryFactory.js +314 -0
  115. package/src/geometry/GeometryLibrary.js +72 -0
  116. package/src/geometry/buffers/BufferBuilder.js +338 -0
  117. package/src/geometry/buffers/index.js +18 -0
  118. package/src/geometry/generators/Crystal.js +420 -0
  119. package/src/geometry/generators/Fractal.js +298 -0
  120. package/src/geometry/generators/KleinBottle.js +197 -0
  121. package/src/geometry/generators/Sphere.js +192 -0
  122. package/src/geometry/generators/Tesseract.js +160 -0
  123. package/src/geometry/generators/Tetrahedron.js +225 -0
  124. package/src/geometry/generators/Torus.js +304 -0
  125. package/src/geometry/generators/Wave.js +341 -0
  126. package/src/geometry/index.js +142 -0
  127. package/src/geometry/warp/HypersphereCore.js +211 -0
  128. package/src/geometry/warp/HypertetraCore.js +386 -0
  129. package/src/geometry/warp/index.js +57 -0
  130. package/src/holograms/HolographicVisualizer.js +1073 -0
  131. package/src/holograms/RealHolographicSystem.js +966 -0
  132. package/src/holograms/variantRegistry.js +69 -0
  133. package/src/integrations/FigmaPlugin.js +854 -0
  134. package/src/integrations/OBSMode.js +754 -0
  135. package/src/integrations/ThreeJsPackage.js +660 -0
  136. package/src/integrations/TouchDesignerExport.js +552 -0
  137. package/src/integrations/frameworks/Vib3React.js +591 -0
  138. package/src/integrations/frameworks/Vib3Svelte.js +654 -0
  139. package/src/integrations/frameworks/Vib3Vue.js +628 -0
  140. package/src/llm/LLMParameterInterface.js +240 -0
  141. package/src/llm/LLMParameterUI.js +577 -0
  142. package/src/math/Mat4x4.js +708 -0
  143. package/src/math/Projection.js +341 -0
  144. package/src/math/Rotor4D.js +637 -0
  145. package/src/math/Vec4.js +476 -0
  146. package/src/math/constants.js +164 -0
  147. package/src/math/index.js +68 -0
  148. package/src/math/projections.js +54 -0
  149. package/src/math/rotations.js +196 -0
  150. package/src/quantum/QuantumEngine.js +906 -0
  151. package/src/quantum/QuantumVisualizer.js +1103 -0
  152. package/src/reactivity/ReactivityConfig.js +499 -0
  153. package/src/reactivity/ReactivityManager.js +586 -0
  154. package/src/reactivity/SpatialInputSystem.js +1783 -0
  155. package/src/reactivity/index.js +93 -0
  156. package/src/render/CommandBuffer.js +465 -0
  157. package/src/render/MultiCanvasBridge.js +340 -0
  158. package/src/render/RenderCommand.js +514 -0
  159. package/src/render/RenderResourceRegistry.js +523 -0
  160. package/src/render/RenderState.js +552 -0
  161. package/src/render/RenderTarget.js +512 -0
  162. package/src/render/ShaderLoader.js +253 -0
  163. package/src/render/ShaderProgram.js +599 -0
  164. package/src/render/UnifiedRenderBridge.js +496 -0
  165. package/src/render/backends/WebGLBackend.js +1108 -0
  166. package/src/render/backends/WebGPUBackend.js +1409 -0
  167. package/src/render/commands/CommandBufferExecutor.js +607 -0
  168. package/src/render/commands/RenderCommandBuffer.js +661 -0
  169. package/src/render/commands/index.js +17 -0
  170. package/src/render/index.js +367 -0
  171. package/src/scene/Disposable.js +498 -0
  172. package/src/scene/MemoryPool.js +618 -0
  173. package/src/scene/Node4D.js +697 -0
  174. package/src/scene/ResourceManager.js +599 -0
  175. package/src/scene/Scene4D.js +540 -0
  176. package/src/scene/index.js +98 -0
  177. package/src/schemas/error.schema.json +84 -0
  178. package/src/schemas/extension.schema.json +88 -0
  179. package/src/schemas/index.js +214 -0
  180. package/src/schemas/parameters.schema.json +142 -0
  181. package/src/schemas/tool-pack.schema.json +44 -0
  182. package/src/schemas/tool-response.schema.json +127 -0
  183. package/src/shaders/common/fullscreen.vert.glsl +5 -0
  184. package/src/shaders/common/fullscreen.vert.wgsl +17 -0
  185. package/src/shaders/common/geometry24.glsl +65 -0
  186. package/src/shaders/common/geometry24.wgsl +54 -0
  187. package/src/shaders/common/rotation4d.glsl +85 -0
  188. package/src/shaders/common/rotation4d.wgsl +86 -0
  189. package/src/shaders/common/uniforms.glsl +44 -0
  190. package/src/shaders/common/uniforms.wgsl +48 -0
  191. package/src/shaders/faceted/faceted.frag.glsl +129 -0
  192. package/src/shaders/faceted/faceted.frag.wgsl +164 -0
  193. package/src/shaders/holographic/holographic.frag.glsl +406 -0
  194. package/src/shaders/holographic/holographic.frag.wgsl +185 -0
  195. package/src/shaders/quantum/quantum.frag.glsl +513 -0
  196. package/src/shaders/quantum/quantum.frag.wgsl +361 -0
  197. package/src/testing/ParallelTestFramework.js +519 -0
  198. package/src/testing/__snapshots__/exportFormats.test.js.snap +24 -0
  199. package/src/testing/exportFormats.test.js +8 -0
  200. package/src/testing/projections.test.js +14 -0
  201. package/src/testing/rotations.test.js +37 -0
  202. package/src/ui/InteractivityMenu.js +516 -0
  203. package/src/ui/StatusManager.js +96 -0
  204. package/src/ui/adaptive/renderers/webgpu/BufferLayout.ts +252 -0
  205. package/src/ui/adaptive/renderers/webgpu/PolytopeInstanceBuffer.ts +144 -0
  206. package/src/ui/adaptive/renderers/webgpu/TripleBufferedUniform.ts +170 -0
  207. package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +735 -0
  208. package/src/ui/adaptive/renderers/webgpu/index.ts +112 -0
  209. package/src/variations/VariationManager.js +431 -0
  210. package/src/viewer/AudioReactivity.js +505 -0
  211. package/src/viewer/CardBending.js +481 -0
  212. package/src/viewer/GalleryUI.js +832 -0
  213. package/src/viewer/ReactivityManager.js +590 -0
  214. package/src/viewer/TradingCardExporter.js +600 -0
  215. package/src/viewer/ViewerPortal.js +374 -0
  216. package/src/viewer/index.js +12 -0
  217. package/src/wasm/WasmLoader.js +296 -0
  218. package/src/wasm/index.js +132 -0
  219. package/tools/agentic/mcpTools.js +88 -0
  220. package/tools/cli/agent-cli.js +92 -0
  221. package/tools/export/formats.js +24 -0
  222. package/tools/math/rotation-baseline.mjs +64 -0
  223. package/tools/shader-sync-verify.js +937 -0
  224. package/tools/telemetry/manifestPipeline.js +141 -0
  225. package/tools/telemetry/telemetryEvents.js +35 -0
  226. package/types/adaptive-sdk.d.ts +185 -0
  227. package/types/advanced/AIPresetGenerator.d.ts +81 -0
  228. package/types/advanced/MIDIController.d.ts +100 -0
  229. package/types/advanced/OffscreenWorker.d.ts +82 -0
  230. package/types/advanced/WebGPUCompute.d.ts +52 -0
  231. package/types/advanced/WebXRRenderer.d.ts +77 -0
  232. package/types/advanced/index.d.ts +46 -0
  233. package/types/core/ErrorReporter.d.ts +50 -0
  234. package/types/core/VIB3Engine.d.ts +204 -0
  235. package/types/creative/ColorPresetsSystem.d.ts +91 -0
  236. package/types/creative/ParameterTimeline.d.ts +74 -0
  237. package/types/creative/PostProcessingPipeline.d.ts +109 -0
  238. package/types/creative/TransitionAnimator.d.ts +71 -0
  239. package/types/creative/index.d.ts +35 -0
  240. package/types/integrations/FigmaPlugin.d.ts +46 -0
  241. package/types/integrations/OBSMode.d.ts +74 -0
  242. package/types/integrations/ThreeJsPackage.d.ts +62 -0
  243. package/types/integrations/TouchDesignerExport.d.ts +36 -0
  244. package/types/integrations/Vib3React.d.ts +74 -0
  245. package/types/integrations/Vib3Svelte.d.ts +63 -0
  246. package/types/integrations/Vib3Vue.d.ts +55 -0
  247. package/types/integrations/index.d.ts +52 -0
  248. package/types/reactivity/SpatialInputSystem.d.ts +173 -0
  249. package/types/reactivity/index.d.ts +394 -0
  250. package/types/render/CommandBuffer.d.ts +169 -0
  251. package/types/render/RenderCommand.d.ts +312 -0
  252. package/types/render/RenderState.d.ts +279 -0
  253. package/types/render/RenderTarget.d.ts +254 -0
  254. package/types/render/ShaderProgram.d.ts +277 -0
  255. package/types/render/UnifiedRenderBridge.d.ts +143 -0
  256. package/types/render/WebGLBackend.d.ts +168 -0
  257. package/types/render/WebGPUBackend.d.ts +186 -0
  258. package/types/render/index.d.ts +141 -0
@@ -0,0 +1,963 @@
1
+ /**
2
+ * Faceted System - Clean 2D Geometric Patterns with 4D Rotation
3
+ * Supports 24 geometry variants: 8 base + 8 Hypersphere Core + 8 Hypertetrahedron Core
4
+ * Full 6D rotation mathematics (XY, XZ, YZ, XW, YW, ZW)
5
+ *
6
+ * Supports both WebGL (direct) and WebGPU (via UnifiedRenderBridge).
7
+ */
8
+
9
+ import { UnifiedRenderBridge } from '../render/UnifiedRenderBridge.js';
10
+ import { shaderLoader } from '../render/ShaderLoader.js';
11
+
12
+ // ============================================================================
13
+ // Shader Sources
14
+ // ============================================================================
15
+
16
+ const VERTEX_SHADER_GLSL = `
17
+ attribute vec2 a_position;
18
+ void main() {
19
+ gl_Position = vec4(a_position, 0.0, 1.0);
20
+ }
21
+ `;
22
+
23
+ const FRAGMENT_SHADER_GLSL = `
24
+ precision highp float;
25
+
26
+ uniform float u_time;
27
+ uniform vec2 u_resolution;
28
+ uniform vec2 u_mouse;
29
+ uniform float u_geometry; // 0-23
30
+
31
+ // 6D Rotation uniforms
32
+ uniform float u_rot4dXY;
33
+ uniform float u_rot4dXZ;
34
+ uniform float u_rot4dYZ;
35
+ uniform float u_rot4dXW;
36
+ uniform float u_rot4dYW;
37
+ uniform float u_rot4dZW;
38
+
39
+ uniform float u_dimension;
40
+ uniform float u_gridDensity;
41
+ uniform float u_morphFactor;
42
+ uniform float u_chaos;
43
+ uniform float u_speed;
44
+ uniform float u_hue;
45
+ uniform float u_intensity;
46
+ uniform float u_saturation;
47
+ uniform float u_mouseIntensity;
48
+ uniform float u_clickIntensity;
49
+ uniform float u_roleIntensity;
50
+ uniform float u_bass;
51
+ uniform float u_mid;
52
+ uniform float u_high;
53
+
54
+ // ── 6D Rotation Matrices ──
55
+
56
+ mat4 rotateXY(float theta) {
57
+ float c = cos(theta); float s = sin(theta);
58
+ return mat4(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
59
+ }
60
+ mat4 rotateXZ(float theta) {
61
+ float c = cos(theta); float s = sin(theta);
62
+ return mat4(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1);
63
+ }
64
+ mat4 rotateYZ(float theta) {
65
+ float c = cos(theta); float s = sin(theta);
66
+ return mat4(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1);
67
+ }
68
+ mat4 rotateXW(float theta) {
69
+ float c = cos(theta); float s = sin(theta);
70
+ return mat4(c, 0, 0, -s, 0, 1, 0, 0, 0, 0, 1, 0, s, 0, 0, c);
71
+ }
72
+ mat4 rotateYW(float theta) {
73
+ float c = cos(theta); float s = sin(theta);
74
+ return mat4(1, 0, 0, 0, 0, c, 0, -s, 0, 0, 1, 0, 0, s, 0, c);
75
+ }
76
+ mat4 rotateZW(float theta) {
77
+ float c = cos(theta); float s = sin(theta);
78
+ return mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, c, -s, 0, 0, s, c);
79
+ }
80
+
81
+ // ── 4D → 3D Projection ──
82
+
83
+ vec3 project4Dto3D(vec4 p) {
84
+ float w = 2.5 / (2.5 + p.w);
85
+ return vec3(p.x * w, p.y * w, p.z * w);
86
+ }
87
+
88
+ // ── Polytope Core Warp Functions (24 Geometries) ──
89
+
90
+ vec3 warpHypersphereCore(vec3 p, int geometryIndex, vec2 mouseDelta) {
91
+ float radius = length(p);
92
+ float morphBlend = clamp(u_morphFactor * 0.6 + (u_dimension - 3.0) * 0.25, 0.0, 2.0);
93
+ float w = sin(radius * (1.3 + float(geometryIndex) * 0.12) + u_time * 0.0008 * u_speed);
94
+ w *= (0.4 + morphBlend * 0.45);
95
+
96
+ vec4 p4d = vec4(p * (1.0 + morphBlend * 0.2), w);
97
+ p4d = rotateXY(u_rot4dXY) * p4d;
98
+ p4d = rotateXZ(u_rot4dXZ) * p4d;
99
+ p4d = rotateYZ(u_rot4dYZ) * p4d;
100
+ p4d = rotateXW(u_rot4dXW) * p4d;
101
+ p4d = rotateYW(u_rot4dYW) * p4d;
102
+ p4d = rotateZW(u_rot4dZW) * p4d;
103
+
104
+ vec3 projected = project4Dto3D(p4d);
105
+ return mix(p, projected, clamp(0.45 + morphBlend * 0.35, 0.0, 1.0));
106
+ }
107
+
108
+ vec3 warpHypertetraCore(vec3 p, int geometryIndex, vec2 mouseDelta) {
109
+ vec3 c1 = normalize(vec3(1.0, 1.0, 1.0));
110
+ vec3 c2 = normalize(vec3(-1.0, -1.0, 1.0));
111
+ vec3 c3 = normalize(vec3(-1.0, 1.0, -1.0));
112
+ vec3 c4 = normalize(vec3(1.0, -1.0, -1.0));
113
+
114
+ float morphBlend = clamp(u_morphFactor * 0.8 + (u_dimension - 3.0) * 0.2, 0.0, 2.0);
115
+ float basisMix = dot(p, c1) * 0.14 + dot(p, c2) * 0.1 + dot(p, c3) * 0.08;
116
+ float w = sin(basisMix * 5.5 + u_time * 0.0009 * u_speed);
117
+ w *= cos(dot(p, c4) * 4.2 - u_time * 0.0007 * u_speed);
118
+ w *= (0.5 + morphBlend * 0.4);
119
+
120
+ vec3 offset = vec3(dot(p, c1), dot(p, c2), dot(p, c3)) * 0.1 * morphBlend;
121
+ vec4 p4d = vec4(p + offset, w);
122
+ p4d = rotateXY(u_rot4dXY) * p4d;
123
+ p4d = rotateXZ(u_rot4dXZ) * p4d;
124
+ p4d = rotateYZ(u_rot4dYZ) * p4d;
125
+ p4d = rotateXW(u_rot4dXW) * p4d;
126
+ p4d = rotateYW(u_rot4dYW) * p4d;
127
+ p4d = rotateZW(u_rot4dZW) * p4d;
128
+
129
+ vec3 projected = project4Dto3D(p4d);
130
+ float planeInfluence = min(min(abs(dot(p, c1)), abs(dot(p, c2))),
131
+ min(abs(dot(p, c3)), abs(dot(p, c4))));
132
+ vec3 blended = mix(p, projected, clamp(0.45 + morphBlend * 0.35, 0.0, 1.0));
133
+ return mix(blended, blended * (1.0 - planeInfluence * 0.55), 0.2 + morphBlend * 0.2);
134
+ }
135
+
136
+ vec3 applyCoreWarp(vec3 p, float geometryType, vec2 mouseDelta) {
137
+ float totalBase = 8.0;
138
+ float coreFloat = floor(geometryType / totalBase);
139
+ int coreIndex = int(clamp(coreFloat, 0.0, 2.0));
140
+ // WebGL 1.0 compatible modulus
141
+ float baseGeomFloat = geometryType - floor(geometryType / totalBase) * totalBase;
142
+ int geometryIndex = int(clamp(floor(baseGeomFloat + 0.5), 0.0, totalBase - 1.0));
143
+
144
+ if (coreIndex == 1) {
145
+ return warpHypersphereCore(p, geometryIndex, mouseDelta);
146
+ }
147
+ if (coreIndex == 2) {
148
+ return warpHypertetraCore(p, geometryIndex, mouseDelta);
149
+ }
150
+ return p;
151
+ }
152
+
153
+ // ── 8 Lattice Geometry Functions ──
154
+
155
+ float geometryFunction(vec4 p) {
156
+ float totalBase = 8.0;
157
+ // WebGL 1.0 compatible modulus
158
+ float baseGeomFloat = u_geometry - floor(u_geometry / totalBase) * totalBase;
159
+ int geomType = int(clamp(floor(baseGeomFloat + 0.5), 0.0, totalBase - 1.0));
160
+
161
+ if (geomType == 0) {
162
+ // Tetrahedron lattice
163
+ vec4 pos = fract(p * u_gridDensity * 0.08);
164
+ vec4 dist = min(pos, 1.0 - pos);
165
+ return min(min(dist.x, dist.y), min(dist.z, dist.w)) * u_morphFactor;
166
+ }
167
+ else if (geomType == 1) {
168
+ // Hypercube lattice
169
+ vec4 pos = fract(p * u_gridDensity * 0.08);
170
+ vec4 dist = min(pos, 1.0 - pos);
171
+ float minDist = min(min(dist.x, dist.y), min(dist.z, dist.w));
172
+ return minDist * u_morphFactor;
173
+ }
174
+ else if (geomType == 2) {
175
+ // Sphere lattice
176
+ float r = length(p);
177
+ float density = u_gridDensity * 0.08;
178
+ float spheres = abs(fract(r * density) - 0.5) * 2.0;
179
+ float theta = atan(p.y, p.x);
180
+ float harmonics = sin(theta * 3.0) * 0.2;
181
+ return (spheres + harmonics) * u_morphFactor;
182
+ }
183
+ else if (geomType == 3) {
184
+ // Torus lattice
185
+ float r1 = length(p.xy) - 2.0;
186
+ float torus = length(vec2(r1, p.z)) - 0.8;
187
+ float lattice = sin(p.x * u_gridDensity * 0.08) * sin(p.y * u_gridDensity * 0.08);
188
+ return (torus + lattice * 0.3) * u_morphFactor;
189
+ }
190
+ else if (geomType == 4) {
191
+ // Klein bottle lattice
192
+ float u_ang = atan(p.y, p.x);
193
+ float v_ang = atan(p.w, p.z);
194
+ float dist = length(p) - 2.0;
195
+ float lattice = sin(u_ang * u_gridDensity * 0.08) * sin(v_ang * u_gridDensity * 0.08);
196
+ return (dist + lattice * 0.4) * u_morphFactor;
197
+ }
198
+ else if (geomType == 5) {
199
+ // Fractal lattice
200
+ vec4 pos = fract(p * u_gridDensity * 0.08);
201
+ pos = abs(pos * 2.0 - 1.0);
202
+ float dist = length(max(abs(pos) - 1.0, 0.0));
203
+ return dist * u_morphFactor;
204
+ }
205
+ else if (geomType == 6) {
206
+ // Wave lattice
207
+ float freq = u_gridDensity * 0.08;
208
+ float time = u_time * 0.001 * u_speed;
209
+ float wave1 = sin(p.x * freq + time);
210
+ float wave2 = sin(p.y * freq + time * 1.3);
211
+ float wave3 = sin(p.z * freq * 0.8 + time * 0.7);
212
+ float interference = wave1 * wave2 * wave3;
213
+ return interference * u_morphFactor;
214
+ }
215
+ else if (geomType == 7) {
216
+ // Crystal lattice
217
+ vec4 pos = fract(p * u_gridDensity * 0.08) - 0.5;
218
+ float cube = max(max(abs(pos.x), abs(pos.y)), max(abs(pos.z), abs(pos.w)));
219
+ return cube * u_morphFactor;
220
+ }
221
+ else {
222
+ // Default hypercube
223
+ vec4 pos = fract(p * u_gridDensity * 0.08);
224
+ vec4 dist = min(pos, 1.0 - pos);
225
+ return min(min(dist.x, dist.y), min(dist.z, dist.w)) * u_morphFactor;
226
+ }
227
+ }
228
+
229
+ // ── Main ──
230
+
231
+ void main() {
232
+ vec2 uv = (gl_FragCoord.xy - u_resolution.xy * 0.5) / min(u_resolution.x, u_resolution.y);
233
+ float timeSpeed = u_time * 0.0001 * u_speed;
234
+
235
+ // Create 4D point
236
+ vec4 pos = vec4(uv * 3.0, sin(timeSpeed * 3.0), cos(timeSpeed * 2.0));
237
+
238
+ // Mouse influence
239
+ pos.xy += (u_mouse - 0.5) * u_mouseIntensity * 2.0;
240
+
241
+ // Audio-reactive density and morph
242
+ float audioDensityMod = 1.0 + u_bass * 0.3;
243
+ float audioMorphMod = 1.0 + u_mid * 0.2;
244
+
245
+ // Apply full 6D rotation
246
+ pos = rotateXY(u_rot4dXY) * pos;
247
+ pos = rotateXZ(u_rot4dXZ) * pos;
248
+ pos = rotateYZ(u_rot4dYZ) * pos;
249
+ pos = rotateXW(u_rot4dXW) * pos;
250
+ pos = rotateYW(u_rot4dYW) * pos;
251
+ pos = rotateZW(u_rot4dZW) * pos;
252
+
253
+ // 4D → 3D projection
254
+ vec3 basePoint = project4Dto3D(pos);
255
+
256
+ // Apply polytope core warp (types 8-23)
257
+ vec3 warpedPoint = applyCoreWarp(basePoint, u_geometry, u_mouse - 0.5);
258
+
259
+ // Evaluate lattice geometry
260
+ vec4 warpedPos = vec4(warpedPoint, pos.w);
261
+ float value = geometryFunction(warpedPos);
262
+
263
+ // Chaos noise
264
+ float noise = sin(pos.x * 7.0) * cos(pos.y * 11.0) * sin(pos.z * 13.0);
265
+ value += noise * u_chaos;
266
+
267
+ // Intensity from lattice
268
+ float geometryIntensity = 1.0 - clamp(abs(value), 0.0, 1.0);
269
+ geometryIntensity += u_clickIntensity * 0.3;
270
+ float finalIntensity = geometryIntensity * u_intensity;
271
+
272
+ // Audio-reactive hue shift
273
+ float hue = u_hue / 360.0 + value * 0.1 + u_high * 0.08;
274
+
275
+ // Color via sin-wave HSL
276
+ vec3 baseColor = vec3(
277
+ sin(hue * 6.28318 + 0.0) * 0.5 + 0.5,
278
+ sin(hue * 6.28318 + 2.0943) * 0.5 + 0.5,
279
+ sin(hue * 6.28318 + 4.1887) * 0.5 + 0.5
280
+ );
281
+
282
+ // Saturation control (mix to gray)
283
+ float gray = (baseColor.r + baseColor.g + baseColor.b) / 3.0;
284
+ vec3 color = mix(vec3(gray), baseColor, u_saturation) * finalIntensity;
285
+
286
+ gl_FragColor = vec4(color, finalIntensity * u_roleIntensity);
287
+ }
288
+ `;
289
+
290
+ // WGSL version of the faceted fragment shader for WebGPU
291
+ const FRAGMENT_SHADER_WGSL = `
292
+ struct VIB3Uniforms {
293
+ time: f32,
294
+ speed: f32,
295
+ resolution: vec2<f32>,
296
+ geometry: f32,
297
+ rot4dXY: f32,
298
+ rot4dXZ: f32,
299
+ rot4dYZ: f32,
300
+ rot4dXW: f32,
301
+ rot4dYW: f32,
302
+ rot4dZW: f32,
303
+ dimension: f32,
304
+ gridDensity: f32,
305
+ morphFactor: f32,
306
+ chaos: f32,
307
+ hue: f32,
308
+ intensity: f32,
309
+ saturation: f32,
310
+ mouseIntensity: f32,
311
+ clickIntensity: f32,
312
+ roleIntensity: f32,
313
+ bass: f32,
314
+ mid: f32,
315
+ high: f32,
316
+ _pad0: f32,
317
+ mouse: vec2<f32>,
318
+ _pad1: vec2<f32>,
319
+ };
320
+
321
+ @group(0) @binding(0) var<uniform> u: VIB3Uniforms;
322
+
323
+ fn rotateXY_w(theta: f32) -> mat4x4<f32> {
324
+ let c = cos(theta); let s = sin(theta);
325
+ return mat4x4<f32>(
326
+ vec4<f32>(c, -s, 0.0, 0.0), vec4<f32>(s, c, 0.0, 0.0),
327
+ vec4<f32>(0.0, 0.0, 1.0, 0.0), vec4<f32>(0.0, 0.0, 0.0, 1.0));
328
+ }
329
+ fn rotateXZ_w(theta: f32) -> mat4x4<f32> {
330
+ let c = cos(theta); let s = sin(theta);
331
+ return mat4x4<f32>(
332
+ vec4<f32>(c, 0.0, s, 0.0), vec4<f32>(0.0, 1.0, 0.0, 0.0),
333
+ vec4<f32>(-s, 0.0, c, 0.0), vec4<f32>(0.0, 0.0, 0.0, 1.0));
334
+ }
335
+ fn rotateYZ_w(theta: f32) -> mat4x4<f32> {
336
+ let c = cos(theta); let s = sin(theta);
337
+ return mat4x4<f32>(
338
+ vec4<f32>(1.0, 0.0, 0.0, 0.0), vec4<f32>(0.0, c, -s, 0.0),
339
+ vec4<f32>(0.0, s, c, 0.0), vec4<f32>(0.0, 0.0, 0.0, 1.0));
340
+ }
341
+ fn rotateXW_w(theta: f32) -> mat4x4<f32> {
342
+ let c = cos(theta); let s = sin(theta);
343
+ return mat4x4<f32>(
344
+ vec4<f32>(c, 0.0, 0.0, -s), vec4<f32>(0.0, 1.0, 0.0, 0.0),
345
+ vec4<f32>(0.0, 0.0, 1.0, 0.0), vec4<f32>(s, 0.0, 0.0, c));
346
+ }
347
+ fn rotateYW_w(theta: f32) -> mat4x4<f32> {
348
+ let c = cos(theta); let s = sin(theta);
349
+ return mat4x4<f32>(
350
+ vec4<f32>(1.0, 0.0, 0.0, 0.0), vec4<f32>(0.0, c, 0.0, -s),
351
+ vec4<f32>(0.0, 0.0, 1.0, 0.0), vec4<f32>(0.0, s, 0.0, c));
352
+ }
353
+ fn rotateZW_w(theta: f32) -> mat4x4<f32> {
354
+ let c = cos(theta); let s = sin(theta);
355
+ return mat4x4<f32>(
356
+ vec4<f32>(1.0, 0.0, 0.0, 0.0), vec4<f32>(0.0, 1.0, 0.0, 0.0),
357
+ vec4<f32>(0.0, 0.0, c, -s), vec4<f32>(0.0, 0.0, s, c));
358
+ }
359
+
360
+ fn project4Dto3D_w(p: vec4<f32>) -> vec3<f32> {
361
+ let w = 2.5 / (2.5 + p.w);
362
+ return vec3<f32>(p.x * w, p.y * w, p.z * w);
363
+ }
364
+
365
+ fn warpHypersphereCore_w(p: vec3<f32>, geomIdx: i32) -> vec3<f32> {
366
+ let radius = length(p);
367
+ let morphBlend = clamp(u.morphFactor * 0.6 + (u.dimension - 3.0) * 0.25, 0.0, 2.0);
368
+ let w = sin(radius * (1.3 + f32(geomIdx) * 0.12) + u.time * 0.0008 * u.speed)
369
+ * (0.4 + morphBlend * 0.45);
370
+ var p4d = vec4<f32>(p * (1.0 + morphBlend * 0.2), w);
371
+ p4d = rotateXY_w(u.rot4dXY) * p4d;
372
+ p4d = rotateXZ_w(u.rot4dXZ) * p4d;
373
+ p4d = rotateYZ_w(u.rot4dYZ) * p4d;
374
+ p4d = rotateXW_w(u.rot4dXW) * p4d;
375
+ p4d = rotateYW_w(u.rot4dYW) * p4d;
376
+ p4d = rotateZW_w(u.rot4dZW) * p4d;
377
+ let proj = project4Dto3D_w(p4d);
378
+ return mix(p, proj, clamp(0.45 + morphBlend * 0.35, 0.0, 1.0));
379
+ }
380
+
381
+ fn warpHypertetraCore_w(p: vec3<f32>, geomIdx: i32) -> vec3<f32> {
382
+ let c1 = normalize(vec3<f32>(1.0, 1.0, 1.0));
383
+ let c2 = normalize(vec3<f32>(-1.0, -1.0, 1.0));
384
+ let c3 = normalize(vec3<f32>(-1.0, 1.0, -1.0));
385
+ let c4 = normalize(vec3<f32>(1.0, -1.0, -1.0));
386
+ let morphBlend = clamp(u.morphFactor * 0.8 + (u.dimension - 3.0) * 0.2, 0.0, 2.0);
387
+ let basisMix = dot(p, c1) * 0.14 + dot(p, c2) * 0.1 + dot(p, c3) * 0.08;
388
+ let w = sin(basisMix * 5.5 + u.time * 0.0009 * u.speed)
389
+ * cos(dot(p, c4) * 4.2 - u.time * 0.0007 * u.speed)
390
+ * (0.5 + morphBlend * 0.4);
391
+ let offset = vec3<f32>(dot(p, c1), dot(p, c2), dot(p, c3)) * 0.1 * morphBlend;
392
+ var p4d = vec4<f32>(p + offset, w);
393
+ p4d = rotateXY_w(u.rot4dXY) * p4d;
394
+ p4d = rotateXZ_w(u.rot4dXZ) * p4d;
395
+ p4d = rotateYZ_w(u.rot4dYZ) * p4d;
396
+ p4d = rotateXW_w(u.rot4dXW) * p4d;
397
+ p4d = rotateYW_w(u.rot4dYW) * p4d;
398
+ p4d = rotateZW_w(u.rot4dZW) * p4d;
399
+ let proj = project4Dto3D_w(p4d);
400
+ let planeInf = min(min(abs(dot(p, c1)), abs(dot(p, c2))),
401
+ min(abs(dot(p, c3)), abs(dot(p, c4))));
402
+ let blended = mix(p, proj, clamp(0.45 + morphBlend * 0.35, 0.0, 1.0));
403
+ return mix(blended, blended * (1.0 - planeInf * 0.55), 0.2 + morphBlend * 0.2);
404
+ }
405
+
406
+ fn applyCoreWarp_w(p: vec3<f32>, geomType: f32, mouseDelta: vec2<f32>) -> vec3<f32> {
407
+ let coreFloat = floor(geomType / 8.0);
408
+ let coreIndex = i32(clamp(coreFloat, 0.0, 2.0));
409
+ let baseFloat = geomType - coreFloat * 8.0;
410
+ let geomIdx = i32(clamp(floor(baseFloat + 0.5), 0.0, 7.0));
411
+ if (coreIndex == 1) { return warpHypersphereCore_w(p, geomIdx); }
412
+ if (coreIndex == 2) { return warpHypertetraCore_w(p, geomIdx); }
413
+ return p;
414
+ }
415
+
416
+ fn geometryFunction_w(p: vec4<f32>) -> f32 {
417
+ let baseFloat = u.geometry - floor(u.geometry / 8.0) * 8.0;
418
+ let gt = i32(clamp(floor(baseFloat + 0.5), 0.0, 7.0));
419
+ let d = u.gridDensity * 0.08;
420
+ if (gt == 0) {
421
+ let pos = fract(p * d); let dist = min(pos, 1.0 - pos);
422
+ return min(min(dist.x, dist.y), min(dist.z, dist.w)) * u.morphFactor;
423
+ } else if (gt == 1) {
424
+ let pos = fract(p * d); let dist = min(pos, 1.0 - pos);
425
+ return min(min(dist.x, dist.y), min(dist.z, dist.w)) * u.morphFactor;
426
+ } else if (gt == 2) {
427
+ let r = length(p); let sph = abs(fract(r * d) - 0.5) * 2.0;
428
+ let harm = sin(atan2(p.y, p.x) * 3.0) * 0.2;
429
+ return (sph + harm) * u.morphFactor;
430
+ } else if (gt == 3) {
431
+ let r1 = length(p.xy) - 2.0; let tor = length(vec2<f32>(r1, p.z)) - 0.8;
432
+ let lat = sin(p.x * d) * sin(p.y * d);
433
+ return (tor + lat * 0.3) * u.morphFactor;
434
+ } else if (gt == 4) {
435
+ let ua = atan2(p.y, p.x); let va = atan2(p.w, p.z);
436
+ let dist = length(p) - 2.0; let lat = sin(ua * d) * sin(va * d);
437
+ return (dist + lat * 0.4) * u.morphFactor;
438
+ } else if (gt == 5) {
439
+ var pos = fract(p * d); pos = abs(pos * 2.0 - 1.0);
440
+ return length(max(abs(pos) - 1.0, vec4<f32>(0.0))) * u.morphFactor;
441
+ } else if (gt == 6) {
442
+ let t = u.time * 0.001 * u.speed;
443
+ return sin(p.x * d + t) * sin(p.y * d + t * 1.3) * sin(p.z * d * 0.8 + t * 0.7) * u.morphFactor;
444
+ } else {
445
+ let pos = fract(p * d) - 0.5;
446
+ return max(max(abs(pos.x), abs(pos.y)), max(abs(pos.z), abs(pos.w))) * u.morphFactor;
447
+ }
448
+ }
449
+
450
+ struct VertexOutput {
451
+ @builtin(position) position: vec4<f32>,
452
+ @location(0) uv: vec2<f32>,
453
+ };
454
+
455
+ @fragment
456
+ fn main(input: VertexOutput) -> @location(0) vec4<f32> {
457
+ let fragCoord = input.position.xy;
458
+ let uv2 = (fragCoord - u.resolution * 0.5) / min(u.resolution.x, u.resolution.y);
459
+ let timeSpeed = u.time * 0.0001 * u.speed;
460
+
461
+ var pos = vec4<f32>(uv2 * 3.0, sin(timeSpeed * 3.0), cos(timeSpeed * 2.0));
462
+ pos = vec4<f32>(pos.xy + (u.mouse - 0.5) * u.mouseIntensity * 2.0, pos.z, pos.w);
463
+
464
+ pos = rotateXY_w(u.rot4dXY) * pos;
465
+ pos = rotateXZ_w(u.rot4dXZ) * pos;
466
+ pos = rotateYZ_w(u.rot4dYZ) * pos;
467
+ pos = rotateXW_w(u.rot4dXW) * pos;
468
+ pos = rotateYW_w(u.rot4dYW) * pos;
469
+ pos = rotateZW_w(u.rot4dZW) * pos;
470
+
471
+ let basePoint = project4Dto3D_w(pos);
472
+ let warpedPoint = applyCoreWarp_w(basePoint, u.geometry, u.mouse - 0.5);
473
+ let warpedPos = vec4<f32>(warpedPoint, pos.w);
474
+ var value = geometryFunction_w(warpedPos);
475
+
476
+ let noise = sin(pos.x * 7.0) * cos(pos.y * 11.0) * sin(pos.z * 13.0);
477
+ value += noise * u.chaos;
478
+
479
+ var geomIntensity = 1.0 - clamp(abs(value), 0.0, 1.0);
480
+ geomIntensity += u.clickIntensity * 0.3;
481
+ let finalIntensity = geomIntensity * u.intensity;
482
+
483
+ let hueVal = u.hue / 360.0 + value * 0.1 + u.high * 0.08;
484
+ let baseColor = vec3<f32>(
485
+ sin(hueVal * 6.28318 + 0.0) * 0.5 + 0.5,
486
+ sin(hueVal * 6.28318 + 2.0943) * 0.5 + 0.5,
487
+ sin(hueVal * 6.28318 + 4.1887) * 0.5 + 0.5);
488
+ let gray = (baseColor.r + baseColor.g + baseColor.b) / 3.0;
489
+ let color = mix(vec3<f32>(gray), baseColor, u.saturation) * finalIntensity;
490
+
491
+ return vec4<f32>(color, finalIntensity * u.roleIntensity);
492
+ }
493
+ `;
494
+
495
+ // ============================================================================
496
+ // FacetedSystem Class
497
+ // ============================================================================
498
+
499
+ export class FacetedSystem {
500
+ constructor() {
501
+ this.canvas = null;
502
+ this.gl = null;
503
+ this.program = null;
504
+ this.isActive = false;
505
+ this.time = 0;
506
+ this.parameters = {
507
+ geometry: 0,
508
+ rot4dXY: 0, rot4dXZ: 0, rot4dYZ: 0,
509
+ rot4dXW: 0, rot4dYW: 0, rot4dZW: 0,
510
+ gridDensity: 15,
511
+ morphFactor: 1.0,
512
+ chaos: 0.2,
513
+ speed: 1.0,
514
+ hue: 200,
515
+ intensity: 0.7,
516
+ saturation: 0.8,
517
+ dimension: 3.5,
518
+ mouseX: 0.5,
519
+ mouseY: 0.5,
520
+ mouseIntensity: 0.0,
521
+ clickIntensity: 0.0,
522
+ roleIntensity: 1.0,
523
+ bass: 0.0,
524
+ mid: 0.0,
525
+ high: 0.0
526
+ };
527
+
528
+ /** @type {UnifiedRenderBridge|null} */
529
+ this._bridge = null;
530
+
531
+ /** @type {'direct'|'bridge'} Rendering mode */
532
+ this._renderMode = 'direct';
533
+ }
534
+
535
+ /**
536
+ * Initialize with UnifiedRenderBridge for WebGL/WebGPU abstraction.
537
+ * @param {HTMLCanvasElement} canvas
538
+ * @param {object} [options]
539
+ * @param {boolean} [options.preferWebGPU=true]
540
+ * @param {boolean} [options.debug=false]
541
+ * @returns {Promise<boolean>}
542
+ */
543
+ async initWithBridge(canvas, options = {}) {
544
+ this.canvas = canvas;
545
+ try {
546
+ this._bridge = await UnifiedRenderBridge.create(canvas, options);
547
+
548
+ // Try loading external shader files first, fall back to inline
549
+ let sources = {
550
+ glslVertex: VERTEX_SHADER_GLSL,
551
+ glslFragment: FRAGMENT_SHADER_GLSL,
552
+ wgslFragment: FRAGMENT_SHADER_WGSL
553
+ };
554
+
555
+ try {
556
+ const external = await shaderLoader.loadShaderPair('faceted', 'faceted/faceted.frag');
557
+ if (external.glslFragment) {
558
+ sources.glslFragment = external.glslFragment;
559
+ }
560
+ if (external.wgslFragment) {
561
+ sources.wgslFragment = external.wgslFragment;
562
+ }
563
+ if (external.glslVertex) {
564
+ sources.glslVertex = external.glslVertex;
565
+ }
566
+ } catch (loadErr) {
567
+ // External load failed — use inline shaders (already set above)
568
+ }
569
+
570
+ const compiled = this._bridge.compileShader('faceted', sources);
571
+
572
+ if (!compiled) {
573
+ console.error('Failed to compile faceted shaders via bridge');
574
+ return false;
575
+ }
576
+
577
+ this._renderMode = 'bridge';
578
+ console.log(`Faceted System initialized via ${this._bridge.getBackendType()} bridge`);
579
+ return true;
580
+ } catch (e) {
581
+ console.error('Faceted bridge init failed, falling back to direct:', e);
582
+ return this.initialize(canvas);
583
+ }
584
+ }
585
+
586
+ /**
587
+ * Initialize faceted system (direct WebGL mode)
588
+ * Finds canvas by ID in DOM (matches reference architecture)
589
+ */
590
+ initialize(canvasOverride = null) {
591
+ this.canvas = canvasOverride ?? document.getElementById('content-canvas');
592
+ if (!this.canvas) {
593
+ console.error('Faceted canvas (content-canvas) not found in DOM');
594
+ console.log('Looking for canvas IDs:', ['background-canvas', 'shadow-canvas', 'content-canvas', 'highlight-canvas', 'accent-canvas']);
595
+ return false;
596
+ }
597
+
598
+ this.gl = this.canvas.getContext('webgl');
599
+ if (!this.gl) {
600
+ console.error('WebGL not available for Faceted System');
601
+ return false;
602
+ }
603
+
604
+ this._contextLost = false;
605
+
606
+ // WebGL context loss/restore handlers
607
+ this._onContextLost = (e) => {
608
+ e.preventDefault();
609
+ this._contextLost = true;
610
+ console.warn('Faceted: WebGL context lost');
611
+ };
612
+ this._onContextRestored = () => {
613
+ console.log('Faceted: WebGL context restored');
614
+ this._contextLost = false;
615
+ this.createShaderProgram();
616
+ };
617
+ this.canvas.addEventListener('webglcontextlost', this._onContextLost);
618
+ this.canvas.addEventListener('webglcontextrestored', this._onContextRestored);
619
+
620
+ if (!this.createShaderProgram()) {
621
+ console.error('Failed to create faceted shader program');
622
+ return false;
623
+ }
624
+
625
+ this.setupCanvasSize();
626
+ this._renderMode = 'direct';
627
+ console.log('Faceted System initialized on content-canvas');
628
+ return true;
629
+ }
630
+
631
+ /**
632
+ * Create shader program with 6D rotation and 24 geometry support
633
+ */
634
+ createShaderProgram() {
635
+ this.program = this.compileProgram(VERTEX_SHADER_GLSL, FRAGMENT_SHADER_GLSL);
636
+ if (!this.program) return false;
637
+
638
+ // Create fullscreen quad
639
+ const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);
640
+ const buffer = this.gl.createBuffer();
641
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
642
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);
643
+
644
+ return true;
645
+ }
646
+
647
+ /**
648
+ * Compile shader program
649
+ */
650
+ compileProgram(vertexSource, fragmentSource) {
651
+ const vertexShader = this.compileShader(this.gl.VERTEX_SHADER, vertexSource);
652
+ const fragmentShader = this.compileShader(this.gl.FRAGMENT_SHADER, fragmentSource);
653
+
654
+ if (!vertexShader || !fragmentShader) return null;
655
+
656
+ const program = this.gl.createProgram();
657
+ this.gl.attachShader(program, vertexShader);
658
+ this.gl.attachShader(program, fragmentShader);
659
+ this.gl.linkProgram(program);
660
+
661
+ if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
662
+ console.error('Shader program link error:', this.gl.getProgramInfoLog(program));
663
+ return null;
664
+ }
665
+
666
+ return program;
667
+ }
668
+
669
+ /**
670
+ * Compile individual shader
671
+ */
672
+ compileShader(type, source) {
673
+ const shader = this.gl.createShader(type);
674
+ this.gl.shaderSource(shader, source);
675
+ this.gl.compileShader(shader);
676
+
677
+ if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
678
+ console.error('Shader compile error:', this.gl.getShaderInfoLog(shader));
679
+ return null;
680
+ }
681
+
682
+ return shader;
683
+ }
684
+
685
+ /**
686
+ * Setup canvas size
687
+ */
688
+ setupCanvasSize() {
689
+ const rect = this.canvas.parentElement.getBoundingClientRect();
690
+ this.canvas.width = rect.width || 800;
691
+ this.canvas.height = rect.height || 600;
692
+ if (this.gl) {
693
+ this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
694
+ }
695
+ }
696
+
697
+ /**
698
+ * Start rendering
699
+ */
700
+ start() {
701
+ this.isActive = true;
702
+ this.render();
703
+ console.log('Faceted System started');
704
+ }
705
+
706
+ /**
707
+ * Stop rendering
708
+ */
709
+ stop() {
710
+ this.isActive = false;
711
+ console.log('Faceted System stopped');
712
+ }
713
+
714
+ /**
715
+ * Set active state
716
+ */
717
+ setActive(active) {
718
+ if (active) {
719
+ this.start();
720
+ } else {
721
+ this.stop();
722
+ }
723
+ }
724
+
725
+ /**
726
+ * Get the current rendering backend type
727
+ * @returns {'webgl'|'webgpu'|'direct-webgl'}
728
+ */
729
+ getBackendType() {
730
+ if (this._renderMode === 'bridge' && this._bridge) {
731
+ return this._bridge.getBackendType();
732
+ }
733
+ return 'direct-webgl';
734
+ }
735
+
736
+ /**
737
+ * Build uniform object for current parameters
738
+ * @private
739
+ */
740
+ _buildUniforms() {
741
+ return {
742
+ u_time: this.time,
743
+ u_resolution: [this.canvas.width, this.canvas.height],
744
+ u_mouse: [this.parameters.mouseX || 0.5, this.parameters.mouseY || 0.5],
745
+ u_geometry: this.parameters.geometry,
746
+ u_rot4dXY: this.parameters.rot4dXY,
747
+ u_rot4dXZ: this.parameters.rot4dXZ,
748
+ u_rot4dYZ: this.parameters.rot4dYZ,
749
+ u_rot4dXW: this.parameters.rot4dXW,
750
+ u_rot4dYW: this.parameters.rot4dYW,
751
+ u_rot4dZW: this.parameters.rot4dZW,
752
+ u_dimension: this.parameters.dimension,
753
+ u_gridDensity: this.parameters.gridDensity,
754
+ u_morphFactor: this.parameters.morphFactor,
755
+ u_chaos: this.parameters.chaos,
756
+ u_speed: this.parameters.speed,
757
+ u_hue: this.parameters.hue,
758
+ u_intensity: this.parameters.intensity,
759
+ u_saturation: this.parameters.saturation,
760
+ u_mouseIntensity: this.parameters.mouseIntensity || 0,
761
+ u_clickIntensity: this.parameters.clickIntensity || 0,
762
+ u_roleIntensity: this.parameters.roleIntensity || 1.0,
763
+ u_bass: this.parameters.bass || 0,
764
+ u_mid: this.parameters.mid || 0,
765
+ u_high: this.parameters.high || 0
766
+ };
767
+ }
768
+
769
+ /**
770
+ * Render a single frame (bridge mode)
771
+ * @private
772
+ */
773
+ _renderBridgeFrame() {
774
+ if (!this._bridge) return;
775
+ this._bridge.setUniforms(this._buildUniforms());
776
+ this._bridge.render('faceted');
777
+ }
778
+
779
+ /**
780
+ * Render a single frame (direct WebGL mode)
781
+ * @private
782
+ */
783
+ _renderDirectFrame() {
784
+ if (!this.gl || !this.program || this._contextLost) return;
785
+ if (this.gl.isContextLost()) {
786
+ this._contextLost = true;
787
+ return;
788
+ }
789
+
790
+ this.gl.useProgram(this.program);
791
+ this.gl.enable(this.gl.BLEND);
792
+ this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
793
+
794
+ this.gl.clearColor(0, 0, 0, 1);
795
+ this.gl.clear(this.gl.COLOR_BUFFER_BIT);
796
+
797
+ const uniforms = this._buildUniforms();
798
+
799
+ Object.entries(uniforms).forEach(([name, value]) => {
800
+ const location = this.gl.getUniformLocation(this.program, name);
801
+ if (location !== null) {
802
+ if (Array.isArray(value)) {
803
+ this.gl.uniform2fv(location, value);
804
+ } else {
805
+ this.gl.uniform1f(location, value);
806
+ }
807
+ }
808
+ });
809
+
810
+ // Draw fullscreen quad
811
+ const posLocation = this.gl.getAttribLocation(this.program, 'a_position');
812
+ this.gl.enableVertexAttribArray(posLocation);
813
+ this.gl.vertexAttribPointer(posLocation, 2, this.gl.FLOAT, false, 0, 0);
814
+ this.gl.drawArrays(this.gl.TRIANGLES, 0, 6);
815
+ }
816
+
817
+ /**
818
+ * Render a single frame
819
+ */
820
+ renderFrame() {
821
+ if (!this.isActive) return;
822
+
823
+ // Apply audio reactivity
824
+ if (window.audioEnabled && window.audioReactive) {
825
+ this.parameters.bass = window.audioReactive.bass || 0;
826
+ this.parameters.mid = window.audioReactive.mid || 0;
827
+ this.parameters.high = window.audioReactive.high || 0;
828
+ }
829
+
830
+ this.time += 0.016 * this.parameters.speed;
831
+
832
+ if (this._renderMode === 'bridge') {
833
+ this._renderBridgeFrame();
834
+ } else {
835
+ this._renderDirectFrame();
836
+ }
837
+ }
838
+
839
+ /**
840
+ * Render loop
841
+ */
842
+ render(frameState = {}) {
843
+ // Apply frameState parameters if provided
844
+ if (frameState.params) {
845
+ Object.assign(this.parameters, frameState.params);
846
+ }
847
+ if (typeof frameState.time === 'number') {
848
+ this.time = frameState.time;
849
+ }
850
+
851
+ this.renderFrame();
852
+
853
+ if (this.isActive) {
854
+ requestAnimationFrame(() => this.render());
855
+ }
856
+ }
857
+
858
+ /**
859
+ * Update parameters with validation
860
+ */
861
+ updateParameters(params) {
862
+ if (!params || typeof params !== 'object') return;
863
+ for (const [key, value] of Object.entries(params)) {
864
+ // Only accept finite numbers to prevent NaN/Infinity reaching shaders
865
+ if (typeof value === 'number' && Number.isFinite(value)) {
866
+ this.parameters[key] = value;
867
+ }
868
+ }
869
+ }
870
+
871
+ // ============================================
872
+ // RendererContract Compliance Methods
873
+ // ============================================
874
+
875
+ /**
876
+ * Initialize the renderer (RendererContract.init)
877
+ * @param {Object} [context] - Optional context with canvas or canvasId
878
+ * @returns {boolean|Promise<boolean>} Success status
879
+ */
880
+ init(context = {}) {
881
+ const canvasOverride = context.canvas ||
882
+ (context.canvasId ? document.getElementById(context.canvasId) : null);
883
+
884
+ // If preferWebGPU is set and canvas is provided, use bridge mode
885
+ if (context.preferWebGPU && canvasOverride) {
886
+ return this.initWithBridge(canvasOverride, {
887
+ preferWebGPU: true,
888
+ debug: context.debug
889
+ });
890
+ }
891
+
892
+ return this.initialize(canvasOverride);
893
+ }
894
+
895
+ /**
896
+ * Handle canvas resize (RendererContract.resize)
897
+ * @param {number} width
898
+ * @param {number} height
899
+ * @param {number} [pixelRatio=1]
900
+ */
901
+ resize(width, height, pixelRatio = 1) {
902
+ if (!this.canvas) return;
903
+
904
+ if (this._renderMode === 'bridge' && this._bridge) {
905
+ this._bridge.resize(width, height, pixelRatio);
906
+ } else if (this.gl) {
907
+ this.canvas.width = width * pixelRatio;
908
+ this.canvas.height = height * pixelRatio;
909
+ this.canvas.style.width = `${width}px`;
910
+ this.canvas.style.height = `${height}px`;
911
+ this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
912
+ }
913
+ }
914
+
915
+ /**
916
+ * Clean up all resources (RendererContract.dispose)
917
+ */
918
+ dispose() {
919
+ this.isActive = false;
920
+
921
+ // Remove context loss listeners
922
+ if (this.canvas) {
923
+ if (this._onContextLost) {
924
+ this.canvas.removeEventListener('webglcontextlost', this._onContextLost);
925
+ }
926
+ if (this._onContextRestored) {
927
+ this.canvas.removeEventListener('webglcontextrestored', this._onContextRestored);
928
+ }
929
+ }
930
+
931
+ if (this._bridge) {
932
+ this._bridge.dispose();
933
+ this._bridge = null;
934
+ }
935
+
936
+ if (this.gl && !this.gl.isContextLost()) {
937
+ if (this.program) {
938
+ this.gl.deleteProgram(this.program);
939
+ }
940
+ }
941
+ this.program = null;
942
+
943
+ if (this.gl) {
944
+ const loseContext = this.gl.getExtension('WEBGL_lose_context');
945
+ if (loseContext) {
946
+ loseContext.loseContext();
947
+ }
948
+ this.gl = null;
949
+ }
950
+
951
+ this.canvas = null;
952
+ this._renderMode = 'direct';
953
+ this._contextLost = true;
954
+ console.log('Faceted System disposed');
955
+ }
956
+
957
+ /**
958
+ * Alias for dispose (for backward compatibility)
959
+ */
960
+ destroy() {
961
+ this.dispose();
962
+ }
963
+ }