@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,1103 @@
1
+ /**
2
+ * VIB34D Quantum Holographic Visualizer
3
+ * Enhanced WebGL renderer with complex 3D lattice functions and holographic effects
4
+ * This is the superior system with volumetric lighting, particles, and RGB glitch effects
5
+ */
6
+
7
+ import { GeometryLibrary } from '../geometry/GeometryLibrary.js';
8
+
9
+ export class QuantumHolographicVisualizer {
10
+ constructor(canvasIdOrElement, role, reactivity, variant) {
11
+ this.canvas = (canvasIdOrElement instanceof HTMLCanvasElement)
12
+ ? canvasIdOrElement
13
+ : document.getElementById(canvasIdOrElement);
14
+ this.role = role;
15
+ this.reactivity = reactivity;
16
+ this.variant = variant;
17
+
18
+ // CRITICAL FIX: Define contextOptions as instance property to match SmartCanvasPool
19
+ this.contextOptions = {
20
+ alpha: true,
21
+ depth: true,
22
+ stencil: false,
23
+ antialias: false, // Disable antialiasing on mobile for performance
24
+ premultipliedAlpha: true,
25
+ preserveDrawingBuffer: false,
26
+ powerPreference: 'high-performance',
27
+ failIfMajorPerformanceCaveat: false // Don't fail on mobile
28
+ };
29
+
30
+ // CRITICAL FIX: Don't create context here - let SmartCanvasPool handle it
31
+ // Try WebGL2 first (better mobile support), then WebGL1
32
+ this.gl = this.canvas.getContext('webgl2', this.contextOptions) ||
33
+ this.canvas.getContext('webgl', this.contextOptions) ||
34
+ this.canvas.getContext('experimental-webgl', this.contextOptions);
35
+
36
+ if (!this.gl) {
37
+ console.error(`WebGL not supported for ${canvasId}`);
38
+ if (window.mobileDebug) {
39
+ window.mobileDebug.log(`❌ ${canvasId}: WebGL context creation failed`);
40
+ }
41
+ // Show user-friendly error instead of white screen
42
+ this.showWebGLError();
43
+ return;
44
+ } else {
45
+ if (window.mobileDebug) {
46
+ const version = this.gl.getParameter(this.gl.VERSION);
47
+ window.mobileDebug.log(`✅ ${canvasId}: WebGL context created - ${version}`);
48
+ }
49
+ }
50
+
51
+ this.mouseX = 0.5;
52
+ this.mouseY = 0.5;
53
+ this.mouseIntensity = 0.0;
54
+ this.clickIntensity = 0.0;
55
+ this.startTime = Date.now();
56
+ this._contextLost = false;
57
+
58
+ // WebGL context loss/restore handlers
59
+ this._onContextLost = (e) => {
60
+ e.preventDefault();
61
+ this._contextLost = true;
62
+ console.warn(`WebGL context lost for ${canvasId}`);
63
+ };
64
+ this._onContextRestored = () => {
65
+ console.log(`WebGL context restored for ${canvasId}`);
66
+ this._contextLost = false;
67
+ try {
68
+ this.init();
69
+ } catch (err) {
70
+ console.error(`Failed to reinit after context restore for ${canvasId}:`, err);
71
+ }
72
+ };
73
+ this.canvas.addEventListener('webglcontextlost', this._onContextLost);
74
+ this.canvas.addEventListener('webglcontextrestored', this._onContextRestored);
75
+
76
+ // Default parameters
77
+ this.params = {
78
+ geometry: 0,
79
+ gridDensity: 15,
80
+ morphFactor: 1.0,
81
+ chaos: 0.2,
82
+ speed: 1.0,
83
+ hue: 200,
84
+ intensity: 0.5,
85
+ saturation: 0.8,
86
+ dimension: 3.5,
87
+ rot4dXY: 0.0,
88
+ rot4dXZ: 0.0,
89
+ rot4dYZ: 0.0,
90
+ rot4dXW: 0.0,
91
+ rot4dYW: 0.0,
92
+ rot4dZW: 0.0
93
+ };
94
+
95
+ this.init();
96
+ }
97
+
98
+ /**
99
+ * CRITICAL FIX: Ensure canvas is properly sized before creating WebGL context
100
+ */
101
+ async ensureCanvasSizedThenInitWebGL() {
102
+ // Set proper canvas dimensions for mobile - with fallbacks
103
+ let rect = this.canvas.getBoundingClientRect();
104
+ const devicePixelRatio = Math.min(window.devicePixelRatio || 1, 2); // Cap at 2x for performance
105
+
106
+ // If canvas has no dimensions, wait for layout or use viewport
107
+ if (rect.width === 0 || rect.height === 0) {
108
+ // Wait for layout with promise
109
+ await new Promise(resolve => {
110
+ setTimeout(() => {
111
+ rect = this.canvas.getBoundingClientRect();
112
+ if (rect.width === 0 || rect.height === 0) {
113
+ // Use viewport dimensions as fallback
114
+ const viewWidth = window.innerWidth;
115
+ const viewHeight = window.innerHeight;
116
+ this.canvas.width = viewWidth * devicePixelRatio;
117
+ this.canvas.height = viewHeight * devicePixelRatio;
118
+
119
+ if (window.mobileDebug) {
120
+ window.mobileDebug.log(`📐 Quantum Canvas ${this.canvas.id}: Using viewport fallback ${this.canvas.width}x${this.canvas.height}`);
121
+ }
122
+ } else {
123
+ this.canvas.width = rect.width * devicePixelRatio;
124
+ this.canvas.height = rect.height * devicePixelRatio;
125
+
126
+ if (window.mobileDebug) {
127
+ window.mobileDebug.log(`📐 Quantum Canvas ${this.canvas.id}: Layout ready ${this.canvas.width}x${this.canvas.height}`);
128
+ }
129
+ }
130
+ resolve();
131
+ }, 100);
132
+ });
133
+ } else {
134
+ this.canvas.width = rect.width * devicePixelRatio;
135
+ this.canvas.height = rect.height * devicePixelRatio;
136
+
137
+ if (window.mobileDebug) {
138
+ window.mobileDebug.log(`📐 Quantum Canvas ${this.canvas.id}: ${this.canvas.width}x${this.canvas.height} (DPR: ${devicePixelRatio})`);
139
+ }
140
+ }
141
+
142
+ // NOW create WebGL context with properly sized canvas
143
+ this.createWebGLContext();
144
+
145
+ // Initialize rendering pipeline
146
+ if (this.gl) {
147
+ this.init();
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Create WebGL context after canvas is properly sized
153
+ */
154
+ createWebGLContext() {
155
+ // CRITICAL FIX: Check if context already exists from SmartCanvasPool
156
+ let existingContext = this.canvas.getContext('webgl2') ||
157
+ this.canvas.getContext('webgl') ||
158
+ this.canvas.getContext('experimental-webgl');
159
+
160
+ if (existingContext && !existingContext.isContextLost()) {
161
+ console.log(`🔄 Reusing existing WebGL context for ${this.canvas.id}`);
162
+ this.gl = existingContext;
163
+ return;
164
+ }
165
+
166
+ // Try WebGL2 first (better mobile support), then WebGL1
167
+ this.gl = this.canvas.getContext('webgl2', this.contextOptions) ||
168
+ this.canvas.getContext('webgl', this.contextOptions) ||
169
+ this.canvas.getContext('experimental-webgl', this.contextOptions);
170
+
171
+ if (!this.gl) {
172
+ console.error(`WebGL not supported for ${this.canvas.id}`);
173
+ if (window.mobileDebug) {
174
+ window.mobileDebug.log(`❌ Quantum ${this.canvas.id}: WebGL context creation failed (size: ${this.canvas.width}x${this.canvas.height})`);
175
+ }
176
+ // Show user-friendly error instead of white screen
177
+ this.showWebGLError();
178
+ return;
179
+ } else {
180
+ if (window.mobileDebug) {
181
+ const version = this.gl.getParameter(this.gl.VERSION);
182
+ window.mobileDebug.log(`✅ Quantum ${this.canvas.id}: WebGL context created - ${version} (size: ${this.canvas.width}x${this.canvas.height})`);
183
+ }
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Initialize WebGL rendering pipeline
189
+ */
190
+ init() {
191
+ this.initShaders();
192
+ this.initBuffers();
193
+ this.resize();
194
+ }
195
+
196
+ /**
197
+ * Reinitialize WebGL context and resources after SmartCanvasPool context recreation
198
+ */
199
+ reinitializeContext() {
200
+ console.log(`🔄 Reinitializing WebGL context for ${this.canvas.id}`);
201
+
202
+ // CRITICAL FIX: Clear old WebGL references first
203
+ this.program = null;
204
+ this.buffer = null;
205
+ this.uniforms = null;
206
+ this.gl = null;
207
+
208
+ // CRITICAL FIX: Don't create new context - SmartCanvasPool already did this
209
+ // Just get the existing context that SmartCanvasPool created
210
+ this.gl = this.canvas.getContext('webgl2') ||
211
+ this.canvas.getContext('webgl') ||
212
+ this.canvas.getContext('experimental-webgl');
213
+
214
+ if (!this.gl) {
215
+ console.error(`❌ No WebGL context available for ${this.canvas.id} - SmartCanvasPool should have created one`);
216
+ return false;
217
+ }
218
+
219
+ if (this.gl.isContextLost()) {
220
+ console.error(`❌ WebGL context is lost for ${this.canvas.id}`);
221
+ return false;
222
+ }
223
+
224
+ // Reinitialize all WebGL resources with the existing context
225
+ try {
226
+ this.initShaders();
227
+ this.initBuffers();
228
+ this.resize();
229
+
230
+ console.log(`✅ WebGL context reinitialized for ${this.canvas.id}`);
231
+ return true;
232
+ } catch (error) {
233
+ console.error(`❌ Failed to reinitialize WebGL resources for ${this.canvas.id}:`, error);
234
+ return false;
235
+ }
236
+ }
237
+
238
+ /**
239
+ * Initialize shaders with complex 3D lattice functions and holographic effects
240
+ */
241
+ initShaders() {
242
+ const vertexShaderSource = `attribute vec2 a_position;
243
+ void main() {
244
+ gl_Position = vec4(a_position, 0.0, 1.0);
245
+ }`;
246
+
247
+ // Mobile-friendly precision - try highp, fallback to mediump
248
+ const isMobile = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
249
+ const precision = isMobile ? 'mediump' : 'highp';
250
+
251
+ const fragmentShaderSource = `
252
+ #ifdef GL_FRAGMENT_PRECISION_HIGH
253
+ precision highp float;
254
+ #else
255
+ precision mediump float;
256
+ #endif
257
+
258
+ uniform vec2 u_resolution;
259
+ uniform float u_time;
260
+ uniform vec2 u_mouse;
261
+ uniform float u_geometry;
262
+ uniform float u_gridDensity;
263
+ uniform float u_morphFactor;
264
+ uniform float u_chaos;
265
+ uniform float u_speed;
266
+ uniform float u_hue;
267
+ uniform float u_intensity;
268
+ uniform float u_saturation;
269
+ uniform float u_dimension;
270
+ uniform float u_rot4dXY;
271
+ uniform float u_rot4dXZ;
272
+ uniform float u_rot4dYZ;
273
+ uniform float u_rot4dXW;
274
+ uniform float u_rot4dYW;
275
+ uniform float u_rot4dZW;
276
+ uniform float u_mouseIntensity;
277
+ uniform float u_clickIntensity;
278
+ uniform float u_roleIntensity;
279
+
280
+ // 6D rotation matrices - 3D space rotations (XY, XZ, YZ)
281
+ mat4 rotateXY(float theta) {
282
+ float c = cos(theta);
283
+ float s = sin(theta);
284
+ return mat4(c, -s, 0.0, 0.0, s, c, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
285
+ }
286
+
287
+ mat4 rotateXZ(float theta) {
288
+ float c = cos(theta);
289
+ float s = sin(theta);
290
+ return mat4(c, 0.0, s, 0.0, 0.0, 1.0, 0.0, 0.0, -s, 0.0, c, 0.0, 0.0, 0.0, 0.0, 1.0);
291
+ }
292
+
293
+ mat4 rotateYZ(float theta) {
294
+ float c = cos(theta);
295
+ float s = sin(theta);
296
+ return mat4(1.0, 0.0, 0.0, 0.0, 0.0, c, -s, 0.0, 0.0, s, c, 0.0, 0.0, 0.0, 0.0, 1.0);
297
+ }
298
+
299
+ // 4D hyperspace rotations (XW, YW, ZW)
300
+ mat4 rotateXW(float theta) {
301
+ float c = cos(theta);
302
+ float s = sin(theta);
303
+ return mat4(c, 0.0, 0.0, -s, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, s, 0.0, 0.0, c);
304
+ }
305
+
306
+ mat4 rotateYW(float theta) {
307
+ float c = cos(theta);
308
+ float s = sin(theta);
309
+ return mat4(1.0, 0.0, 0.0, 0.0, 0.0, c, 0.0, -s, 0.0, 0.0, 1.0, 0.0, 0.0, s, 0.0, c);
310
+ }
311
+
312
+ mat4 rotateZW(float theta) {
313
+ float c = cos(theta);
314
+ float s = sin(theta);
315
+ return mat4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, c, -s, 0.0, 0.0, s, c);
316
+ }
317
+
318
+ vec3 project4Dto3D(vec4 p) {
319
+ float w = 2.5 / (2.5 + p.w);
320
+ return vec3(p.x * w, p.y * w, p.z * w);
321
+ }
322
+
323
+ // ========================================
324
+ // POLYTOPE CORE WARP FUNCTIONS (24 Geometries)
325
+ // ========================================
326
+ vec3 warpHypersphereCore(vec3 p, int geometryIndex, vec2 mouseDelta) {
327
+ float radius = length(p);
328
+ float morphBlend = clamp(u_morphFactor * 0.6 + (u_dimension - 3.0) * 0.25, 0.0, 2.0);
329
+ float w = sin(radius * (1.3 + float(geometryIndex) * 0.12) + u_time * 0.0008 * u_speed);
330
+ w *= (0.4 + morphBlend * 0.45);
331
+
332
+ vec4 p4d = vec4(p * (1.0 + morphBlend * 0.2), w);
333
+ p4d = rotateXY(u_rot4dXY) * p4d;
334
+ p4d = rotateXZ(u_rot4dXZ) * p4d;
335
+ p4d = rotateYZ(u_rot4dYZ) * p4d;
336
+ p4d = rotateXW(u_rot4dXW) * p4d;
337
+ p4d = rotateYW(u_rot4dYW) * p4d;
338
+ p4d = rotateZW(u_rot4dZW) * p4d;
339
+
340
+ vec3 projected = project4Dto3D(p4d);
341
+ return mix(p, projected, clamp(0.45 + morphBlend * 0.35, 0.0, 1.0));
342
+ }
343
+
344
+ vec3 warpHypertetraCore(vec3 p, int geometryIndex, vec2 mouseDelta) {
345
+ vec3 c1 = normalize(vec3(1.0, 1.0, 1.0));
346
+ vec3 c2 = normalize(vec3(-1.0, -1.0, 1.0));
347
+ vec3 c3 = normalize(vec3(-1.0, 1.0, -1.0));
348
+ vec3 c4 = normalize(vec3(1.0, -1.0, -1.0));
349
+
350
+ float morphBlend = clamp(u_morphFactor * 0.8 + (u_dimension - 3.0) * 0.2, 0.0, 2.0);
351
+ float basisMix = dot(p, c1) * 0.14 + dot(p, c2) * 0.1 + dot(p, c3) * 0.08;
352
+ float w = sin(basisMix * 5.5 + u_time * 0.0009 * u_speed);
353
+ w *= cos(dot(p, c4) * 4.2 - u_time * 0.0007 * u_speed);
354
+ w *= (0.5 + morphBlend * 0.4);
355
+
356
+ vec3 offset = vec3(dot(p, c1), dot(p, c2), dot(p, c3)) * 0.1 * morphBlend;
357
+ vec4 p4d = vec4(p + offset, w);
358
+ p4d = rotateXY(u_rot4dXY) * p4d;
359
+ p4d = rotateXZ(u_rot4dXZ) * p4d;
360
+ p4d = rotateYZ(u_rot4dYZ) * p4d;
361
+ p4d = rotateXW(u_rot4dXW) * p4d;
362
+ p4d = rotateYW(u_rot4dYW) * p4d;
363
+ p4d = rotateZW(u_rot4dZW) * p4d;
364
+
365
+ vec3 projected = project4Dto3D(p4d);
366
+
367
+ float planeInfluence = min(min(abs(dot(p, c1)), abs(dot(p, c2))), min(abs(dot(p, c3)), abs(dot(p, c4))));
368
+ vec3 blended = mix(p, projected, clamp(0.45 + morphBlend * 0.35, 0.0, 1.0));
369
+ return mix(blended, blended * (1.0 - planeInfluence * 0.55), 0.2 + morphBlend * 0.2);
370
+ }
371
+
372
+ vec3 applyCoreWarp(vec3 p, float geometryType, vec2 mouseDelta) {
373
+ float totalBase = 8.0;
374
+ float coreFloat = floor(geometryType / totalBase);
375
+ int coreIndex = int(clamp(coreFloat, 0.0, 2.0));
376
+ float baseGeomFloat = mod(geometryType, totalBase);
377
+ int geometryIndex = int(clamp(floor(baseGeomFloat + 0.5), 0.0, totalBase - 1.0));
378
+
379
+ if (coreIndex == 1) {
380
+ return warpHypersphereCore(p, geometryIndex, mouseDelta);
381
+ }
382
+ if (coreIndex == 2) {
383
+ return warpHypertetraCore(p, geometryIndex, mouseDelta);
384
+ }
385
+ return p;
386
+ }
387
+ // ========================================
388
+
389
+ // Complex 3D Lattice Functions - Superior Quantum Shaders
390
+ float tetrahedronLattice(vec3 p, float gridSize) {
391
+ vec3 q = fract(p * gridSize) - 0.5;
392
+ float d1 = length(q);
393
+ float d2 = length(q - vec3(0.4, 0.0, 0.0));
394
+ float d3 = length(q - vec3(0.0, 0.4, 0.0));
395
+ float d4 = length(q - vec3(0.0, 0.0, 0.4));
396
+ float vertices = 1.0 - smoothstep(0.0, 0.04, min(min(d1, d2), min(d3, d4)));
397
+ float edges = 0.0;
398
+ edges = max(edges, 1.0 - smoothstep(0.0, 0.02, abs(length(q.xy) - 0.2)));
399
+ edges = max(edges, 1.0 - smoothstep(0.0, 0.02, abs(length(q.yz) - 0.2)));
400
+ edges = max(edges, 1.0 - smoothstep(0.0, 0.02, abs(length(q.xz) - 0.2)));
401
+ return max(vertices, edges * 0.5);
402
+ }
403
+
404
+ float hypercubeLattice(vec3 p, float gridSize) {
405
+ vec3 grid = fract(p * gridSize);
406
+ vec3 edges = min(grid, 1.0 - grid);
407
+ float minEdge = min(min(edges.x, edges.y), edges.z);
408
+ float lattice = 1.0 - smoothstep(0.0, 0.03, minEdge);
409
+
410
+ vec3 centers = abs(grid - 0.5);
411
+ float maxCenter = max(max(centers.x, centers.y), centers.z);
412
+ float vertices = 1.0 - smoothstep(0.45, 0.5, maxCenter);
413
+
414
+ return max(lattice * 0.7, vertices);
415
+ }
416
+
417
+ float sphereLattice(vec3 p, float gridSize) {
418
+ vec3 cell = fract(p * gridSize) - 0.5;
419
+ float sphere = 1.0 - smoothstep(0.15, 0.25, length(cell));
420
+
421
+ float rings = 0.0;
422
+ float ringRadius = length(cell.xy);
423
+ rings = max(rings, 1.0 - smoothstep(0.0, 0.02, abs(ringRadius - 0.3)));
424
+ rings = max(rings, 1.0 - smoothstep(0.0, 0.02, abs(ringRadius - 0.2)));
425
+
426
+ return max(sphere, rings * 0.6);
427
+ }
428
+
429
+ float torusLattice(vec3 p, float gridSize) {
430
+ vec3 cell = fract(p * gridSize) - 0.5;
431
+ float majorRadius = 0.3;
432
+ float minorRadius = 0.1;
433
+
434
+ float toroidalDist = length(vec2(length(cell.xy) - majorRadius, cell.z));
435
+ float torus = 1.0 - smoothstep(minorRadius - 0.02, minorRadius + 0.02, toroidalDist);
436
+
437
+ float rings = 0.0;
438
+ float angle = atan(cell.y, cell.x);
439
+ rings = sin(angle * 8.0) * 0.02;
440
+
441
+ return max(torus, 0.0) + rings;
442
+ }
443
+
444
+ float kleinLattice(vec3 p, float gridSize) {
445
+ vec3 cell = fract(p * gridSize) - 0.5;
446
+ float u = atan(cell.y, cell.x) / 3.14159 + 1.0;
447
+ float v = cell.z + 0.5;
448
+
449
+ float x = (2.0 + cos(u * 0.5)) * cos(u);
450
+ float y = (2.0 + cos(u * 0.5)) * sin(u);
451
+ float z = sin(u * 0.5) + v;
452
+
453
+ vec3 kleinPoint = vec3(x, y, z) * 0.1;
454
+ float dist = length(cell - kleinPoint);
455
+
456
+ return 1.0 - smoothstep(0.1, 0.15, dist);
457
+ }
458
+
459
+ float fractalLattice(vec3 p, float gridSize) {
460
+ vec3 cell = fract(p * gridSize);
461
+ cell = abs(cell * 2.0 - 1.0);
462
+
463
+ float dist = length(max(abs(cell) - 0.3, 0.0));
464
+
465
+ // Recursive subdivision
466
+ for(int i = 0; i < 3; i++) {
467
+ cell = abs(cell * 2.0 - 1.0);
468
+ float subdist = length(max(abs(cell) - 0.3, 0.0)) / pow(2.0, float(i + 1));
469
+ dist = min(dist, subdist);
470
+ }
471
+
472
+ return 1.0 - smoothstep(0.0, 0.05, dist);
473
+ }
474
+
475
+ float waveLattice(vec3 p, float gridSize) {
476
+ float time = u_time * 0.001 * u_speed;
477
+ vec3 cell = fract(p * gridSize) - 0.5;
478
+
479
+ float wave1 = sin(p.x * gridSize * 2.0 + time * 2.0);
480
+ float wave2 = sin(p.y * gridSize * 1.8 + time * 1.5);
481
+ float wave3 = sin(p.z * gridSize * 2.2 + time * 1.8);
482
+
483
+ float interference = (wave1 + wave2 + wave3) / 3.0;
484
+ float amplitude = 1.0 - length(cell) * 2.0;
485
+
486
+ return max(0.0, interference * amplitude);
487
+ }
488
+
489
+ float crystalLattice(vec3 p, float gridSize) {
490
+ vec3 cell = fract(p * gridSize) - 0.5;
491
+
492
+ // Octahedral crystal structure
493
+ float crystal = max(max(abs(cell.x) + abs(cell.y), abs(cell.y) + abs(cell.z)), abs(cell.x) + abs(cell.z));
494
+ crystal = 1.0 - smoothstep(0.3, 0.4, crystal);
495
+
496
+ // Add crystalline faces
497
+ float faces = 0.0;
498
+ faces = max(faces, 1.0 - smoothstep(0.0, 0.02, abs(abs(cell.x) - 0.35)));
499
+ faces = max(faces, 1.0 - smoothstep(0.0, 0.02, abs(abs(cell.y) - 0.35)));
500
+ faces = max(faces, 1.0 - smoothstep(0.0, 0.02, abs(abs(cell.z) - 0.35)));
501
+
502
+ return max(crystal, faces * 0.5);
503
+ }
504
+
505
+ // Enhanced geometry function with holographic effects (24 GEOMETRIES)
506
+ float geometryFunction(vec4 p) {
507
+ // Decode geometry: base = geometry % 8 (supports 24 geometries)
508
+ float totalBase = 8.0;
509
+ float baseGeomFloat = mod(u_geometry, totalBase);
510
+ int geomType = int(clamp(floor(baseGeomFloat + 0.5), 0.0, totalBase - 1.0));
511
+
512
+ // Project to 3D and apply polytope warp
513
+ vec3 p3d = project4Dto3D(p);
514
+ vec3 warped = applyCoreWarp(p3d, u_geometry, vec2(0.0, 0.0));
515
+ float gridSize = u_gridDensity * 0.08;
516
+
517
+ if (geomType == 0) {
518
+ return tetrahedronLattice(warped, gridSize) * u_morphFactor;
519
+ }
520
+ else if (geomType == 1) {
521
+ return hypercubeLattice(warped, gridSize) * u_morphFactor;
522
+ }
523
+ else if (geomType == 2) {
524
+ return sphereLattice(warped, gridSize) * u_morphFactor;
525
+ }
526
+ else if (geomType == 3) {
527
+ return torusLattice(warped, gridSize) * u_morphFactor;
528
+ }
529
+ else if (geomType == 4) {
530
+ return kleinLattice(warped, gridSize) * u_morphFactor;
531
+ }
532
+ else if (geomType == 5) {
533
+ return fractalLattice(warped, gridSize) * u_morphFactor;
534
+ }
535
+ else if (geomType == 6) {
536
+ return waveLattice(warped, gridSize) * u_morphFactor;
537
+ }
538
+ else if (geomType == 7) {
539
+ return crystalLattice(warped, gridSize) * u_morphFactor;
540
+ }
541
+ else {
542
+ return hypercubeLattice(warped, gridSize) * u_morphFactor;
543
+ }
544
+ }
545
+
546
+ // HSL to RGB conversion for proper color control
547
+ vec3 hsl2rgb(float h, float s, float l) {
548
+ float c = (1.0 - abs(2.0 * l - 1.0)) * s;
549
+ float hp = h * 6.0; // h is 0-1
550
+ float x = c * (1.0 - abs(mod(hp, 2.0) - 1.0));
551
+ float m = l - c * 0.5;
552
+ vec3 rgb;
553
+ if (hp < 1.0) rgb = vec3(c, x, 0.0);
554
+ else if (hp < 2.0) rgb = vec3(x, c, 0.0);
555
+ else if (hp < 3.0) rgb = vec3(0.0, c, x);
556
+ else if (hp < 4.0) rgb = vec3(0.0, x, c);
557
+ else if (hp < 5.0) rgb = vec3(x, 0.0, c);
558
+ else rgb = vec3(c, 0.0, x);
559
+ return rgb + m;
560
+ }
561
+
562
+ // LAYER-BY-LAYER COLOR SYSTEM with user hue/saturation control
563
+ // Each layer gets a hue offset from the user-controlled base hue
564
+ vec3 getLayerColorPalette(int layerIndex, float t) {
565
+ float baseHue = u_hue; // 0-1 from JavaScript (user hue / 360)
566
+ float sat = u_saturation;
567
+
568
+ // Per-layer hue offsets for visual variety
569
+ float hueOffset = 0.0;
570
+ float lightness = 0.5;
571
+
572
+ if (layerIndex == 0) {
573
+ // BACKGROUND: Darkened, shifted hue
574
+ hueOffset = 0.0;
575
+ lightness = 0.15;
576
+ sat *= 0.7;
577
+ }
578
+ else if (layerIndex == 1) {
579
+ // SHADOW: Complementary offset, medium-dark
580
+ hueOffset = 0.33;
581
+ lightness = 0.3;
582
+ sat *= 0.9;
583
+ }
584
+ else if (layerIndex == 2) {
585
+ // CONTENT: Primary hue, bright
586
+ hueOffset = 0.0;
587
+ lightness = 0.55;
588
+ }
589
+ else if (layerIndex == 3) {
590
+ // HIGHLIGHT: Analogous offset, bright
591
+ hueOffset = 0.15;
592
+ lightness = 0.6;
593
+ }
594
+ else {
595
+ // ACCENT: Triadic offset, vivid
596
+ hueOffset = 0.67;
597
+ lightness = 0.5;
598
+ }
599
+
600
+ // Animate hue gently over time and geometry value
601
+ float animatedHue = fract(baseHue + hueOffset + sin(t * 3.0) * 0.05);
602
+ return hsl2rgb(animatedHue, sat, lightness);
603
+ }
604
+
605
+ // Extreme RGB separation and distortion for each layer
606
+ vec3 extremeRGBSeparation(vec3 baseColor, vec2 uv, float intensity, int layerIndex) {
607
+ vec2 offset = vec2(0.01, 0.005) * intensity;
608
+
609
+ // Different separation patterns per layer
610
+ if (layerIndex == 0) {
611
+ // Background: Minimal separation, smooth
612
+ return baseColor + vec3(
613
+ sin(uv.x * 10.0 + u_time * 0.001) * 0.02,
614
+ cos(uv.y * 8.0 + u_time * 0.0015) * 0.02,
615
+ sin(uv.x * uv.y * 6.0 + u_time * 0.0008) * 0.02
616
+ ) * intensity;
617
+ }
618
+ else if (layerIndex == 1) {
619
+ // Shadow: Heavy vertical separation
620
+ float r = baseColor.r + sin(uv.y * 50.0 + u_time * 0.003) * intensity * 0.15;
621
+ float g = baseColor.g + sin((uv.y + 0.1) * 45.0 + u_time * 0.0025) * intensity * 0.12;
622
+ float b = baseColor.b + sin((uv.y - 0.1) * 55.0 + u_time * 0.0035) * intensity * 0.18;
623
+ return vec3(r, g, b);
624
+ }
625
+ else if (layerIndex == 2) {
626
+ // Content: Explosive radial separation
627
+ float dist = length(uv);
628
+ float angle = atan(uv.y, uv.x);
629
+ float r = baseColor.r + sin(dist * 30.0 + angle * 10.0 + u_time * 0.004) * intensity * 0.2;
630
+ float g = baseColor.g + cos(dist * 25.0 + angle * 8.0 + u_time * 0.0035) * intensity * 0.18;
631
+ float b = baseColor.b + sin(dist * 35.0 + angle * 12.0 + u_time * 0.0045) * intensity * 0.22;
632
+ return vec3(r, g, b);
633
+ }
634
+ else if (layerIndex == 3) {
635
+ // Highlight: Lightning-like separation
636
+ float lightning = sin(uv.x * 80.0 + u_time * 0.008) * cos(uv.y * 60.0 + u_time * 0.006);
637
+ float r = baseColor.r + lightning * intensity * 0.25;
638
+ float g = baseColor.g + sin(lightning * 40.0 + u_time * 0.005) * intensity * 0.2;
639
+ float b = baseColor.b + cos(lightning * 30.0 + u_time * 0.007) * intensity * 0.3;
640
+ return vec3(r, g, b);
641
+ }
642
+ else {
643
+ // Accent: Chaotic multi-directional separation
644
+ float chaos1 = sin(uv.x * 100.0 + uv.y * 80.0 + u_time * 0.01);
645
+ float chaos2 = cos(uv.x * 70.0 - uv.y * 90.0 + u_time * 0.008);
646
+ float chaos3 = sin(uv.x * uv.y * 150.0 + u_time * 0.012);
647
+ return baseColor + vec3(chaos1, chaos2, chaos3) * intensity * 0.3;
648
+ }
649
+ }
650
+
651
+ void main() {
652
+ vec2 uv = (gl_FragCoord.xy - u_resolution.xy * 0.5) / min(u_resolution.x, u_resolution.y);
653
+
654
+ // Enhanced 4D position with holographic depth
655
+ float timeSpeed = u_time * 0.0001 * u_speed;
656
+ vec4 pos = vec4(uv * 3.0, sin(timeSpeed * 3.0), cos(timeSpeed * 2.0));
657
+ pos.xy += (u_mouse - 0.5) * u_mouseIntensity * 2.0;
658
+
659
+ // Apply 6D rotations - 3D space rotations first, then 4D hyperspace
660
+ pos = rotateXY(u_rot4dXY) * pos;
661
+ pos = rotateXZ(u_rot4dXZ) * pos;
662
+ pos = rotateYZ(u_rot4dYZ) * pos;
663
+ pos = rotateXW(u_rot4dXW) * pos;
664
+ pos = rotateYW(u_rot4dYW) * pos;
665
+ pos = rotateZW(u_rot4dZW) * pos;
666
+
667
+ // Calculate enhanced geometry value
668
+ float value = geometryFunction(pos);
669
+
670
+ // Enhanced chaos with holographic effects
671
+ float noise = sin(pos.x * 7.0) * cos(pos.y * 11.0) * sin(pos.z * 13.0);
672
+ value += noise * u_chaos;
673
+
674
+ // Enhanced intensity calculation with holographic glow
675
+ float geometryIntensity = 1.0 - clamp(abs(value * 0.8), 0.0, 1.0);
676
+ geometryIntensity = pow(geometryIntensity, 1.5); // More dramatic falloff
677
+ geometryIntensity += u_clickIntensity * 0.3;
678
+
679
+ // Holographic shimmer effect
680
+ float shimmer = sin(uv.x * 20.0 + timeSpeed * 5.0) * cos(uv.y * 15.0 + timeSpeed * 3.0) * 0.1;
681
+ geometryIntensity += shimmer * geometryIntensity;
682
+
683
+ // Apply user intensity control
684
+ float finalIntensity = geometryIntensity * u_intensity;
685
+
686
+ // LAYER-BY-LAYER COLOR SYSTEM with user hue/saturation/intensity controls
687
+ // Determine canvas layer from role/variant (0=background, 1=shadow, 2=content, 3=highlight, 4=accent)
688
+ int layerIndex = 0;
689
+ if (u_roleIntensity == 0.7) layerIndex = 1; // shadow layer
690
+ else if (u_roleIntensity == 1.0) layerIndex = 2; // content layer
691
+ else if (u_roleIntensity == 0.85) layerIndex = 3; // highlight layer
692
+ else if (u_roleIntensity == 0.6) layerIndex = 4; // accent layer
693
+
694
+ // Get layer-specific base color using user hue/saturation controls
695
+ float colorTime = timeSpeed * 2.0 + value * 3.0;
696
+ vec3 layerColor = getLayerColorPalette(layerIndex, colorTime);
697
+
698
+ // Apply geometry-based intensity modulation per layer
699
+ vec3 extremeBaseColor;
700
+ if (layerIndex == 0) {
701
+ // Background: Subtle, fills empty space
702
+ extremeBaseColor = layerColor * (0.3 + geometryIntensity * 0.4);
703
+ }
704
+ else if (layerIndex == 1) {
705
+ // Shadow: Aggressive, high contrast where geometry is weak
706
+ float shadowIntensity = pow(1.0 - geometryIntensity, 2.0); // Inverted for shadows
707
+ extremeBaseColor = layerColor * (shadowIntensity * 0.8 + 0.1);
708
+ }
709
+ else if (layerIndex == 2) {
710
+ // Content: Dominant, follows geometry strongly
711
+ extremeBaseColor = layerColor * (geometryIntensity * 1.2 + 0.2);
712
+ }
713
+ else if (layerIndex == 3) {
714
+ // Highlight: Electric, peaks only
715
+ float peakIntensity = pow(geometryIntensity, 3.0); // Cubic for sharp peaks
716
+ extremeBaseColor = layerColor * (peakIntensity * 1.5 + 0.1);
717
+ }
718
+ else {
719
+ // Accent: Chaotic, random bursts
720
+ float randomBurst = sin(value * 50.0 + timeSpeed * 10.0) * 0.5 + 0.5;
721
+ extremeBaseColor = layerColor * (randomBurst * geometryIntensity * 2.0 + 0.05);
722
+ }
723
+
724
+ // Apply extreme RGB separation per layer
725
+ vec3 extremeColor = extremeRGBSeparation(extremeBaseColor, uv, finalIntensity, layerIndex);
726
+
727
+ // Layer-specific particle systems with extreme colors
728
+ float extremeParticles = 0.0;
729
+ if (layerIndex == 2 || layerIndex == 3) {
730
+ // Only content and highlight layers get particles
731
+ vec2 particleUV = uv * (layerIndex == 2 ? 12.0 : 20.0);
732
+ vec2 particleID = floor(particleUV);
733
+ vec2 particlePos = fract(particleUV) - 0.5;
734
+ float particleDist = length(particlePos);
735
+
736
+ float particleTime = timeSpeed * (layerIndex == 2 ? 3.0 : 8.0) + dot(particleID, vec2(127.1, 311.7));
737
+ float particleAlpha = sin(particleTime) * 0.5 + 0.5;
738
+ float particleSize = layerIndex == 2 ? 0.2 : 0.1;
739
+ extremeParticles = (1.0 - smoothstep(0.05, particleSize, particleDist)) * particleAlpha * 0.4;
740
+ }
741
+
742
+ // Combine color with particles based on layer
743
+ // Particle color derives from user hue for consistency
744
+ vec3 particleColor = hsl2rgb(fract(u_hue + 0.15), u_saturation * 0.5, 0.85);
745
+ vec3 finalColor;
746
+ if (layerIndex == 0) {
747
+ finalColor = extremeColor;
748
+ }
749
+ else if (layerIndex == 1) {
750
+ finalColor = extremeColor * 0.8;
751
+ }
752
+ else if (layerIndex == 2) {
753
+ finalColor = extremeColor + extremeParticles * particleColor;
754
+ }
755
+ else if (layerIndex == 3) {
756
+ finalColor = extremeColor + extremeParticles * particleColor;
757
+ }
758
+ else {
759
+ finalColor = extremeColor * (1.0 + sin(timeSpeed * 20.0) * 0.3);
760
+ }
761
+
762
+ // Layer-specific alpha intensity with extreme contrast
763
+ float layerAlpha;
764
+ if (layerIndex == 0) layerAlpha = 0.6; // Background: Medium
765
+ else if (layerIndex == 1) layerAlpha = 0.4; // Shadow: Lower
766
+ else if (layerIndex == 2) layerAlpha = 1.0; // Content: Full intensity
767
+ else if (layerIndex == 3) layerAlpha = 0.8; // Highlight: High
768
+ else layerAlpha = 0.3; // Accent: Subtle bursts
769
+
770
+ gl_FragColor = vec4(finalColor, finalIntensity * layerAlpha);
771
+ }`;
772
+
773
+ this.program = this.createProgram(vertexShaderSource, fragmentShaderSource);
774
+ this.uniforms = {
775
+ resolution: this.gl.getUniformLocation(this.program, 'u_resolution'),
776
+ time: this.gl.getUniformLocation(this.program, 'u_time'),
777
+ mouse: this.gl.getUniformLocation(this.program, 'u_mouse'),
778
+ geometry: this.gl.getUniformLocation(this.program, 'u_geometry'),
779
+ gridDensity: this.gl.getUniformLocation(this.program, 'u_gridDensity'),
780
+ morphFactor: this.gl.getUniformLocation(this.program, 'u_morphFactor'),
781
+ chaos: this.gl.getUniformLocation(this.program, 'u_chaos'),
782
+ speed: this.gl.getUniformLocation(this.program, 'u_speed'),
783
+ hue: this.gl.getUniformLocation(this.program, 'u_hue'),
784
+ intensity: this.gl.getUniformLocation(this.program, 'u_intensity'),
785
+ saturation: this.gl.getUniformLocation(this.program, 'u_saturation'),
786
+ dimension: this.gl.getUniformLocation(this.program, 'u_dimension'),
787
+ rot4dXY: this.gl.getUniformLocation(this.program, 'u_rot4dXY'),
788
+ rot4dXZ: this.gl.getUniformLocation(this.program, 'u_rot4dXZ'),
789
+ rot4dYZ: this.gl.getUniformLocation(this.program, 'u_rot4dYZ'),
790
+ rot4dXW: this.gl.getUniformLocation(this.program, 'u_rot4dXW'),
791
+ rot4dYW: this.gl.getUniformLocation(this.program, 'u_rot4dYW'),
792
+ rot4dZW: this.gl.getUniformLocation(this.program, 'u_rot4dZW'),
793
+ mouseIntensity: this.gl.getUniformLocation(this.program, 'u_mouseIntensity'),
794
+ clickIntensity: this.gl.getUniformLocation(this.program, 'u_clickIntensity'),
795
+ roleIntensity: this.gl.getUniformLocation(this.program, 'u_roleIntensity')
796
+ };
797
+ }
798
+
799
+ /**
800
+ * Create WebGL program from shaders
801
+ */
802
+ createProgram(vertexSource, fragmentSource) {
803
+ const vertexShader = this.createShader(this.gl.VERTEX_SHADER, vertexSource);
804
+ const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, fragmentSource);
805
+
806
+ if (!vertexShader || !fragmentShader) {
807
+ return null;
808
+ }
809
+
810
+ const program = this.gl.createProgram();
811
+ this.gl.attachShader(program, vertexShader);
812
+ this.gl.attachShader(program, fragmentShader);
813
+ this.gl.linkProgram(program);
814
+
815
+ if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
816
+ const error = this.gl.getProgramInfoLog(program);
817
+ console.error('Program linking failed:', error);
818
+ if (window.mobileDebug) {
819
+ window.mobileDebug.log(`❌ ${this.canvas?.id}: Shader program link failed - ${error}`);
820
+ }
821
+ return null;
822
+ } else {
823
+ if (window.mobileDebug) {
824
+ window.mobileDebug.log(`✅ ${this.canvas?.id}: Shader program linked successfully`);
825
+ }
826
+ }
827
+
828
+ return program;
829
+ }
830
+
831
+ /**
832
+ * Create individual shader
833
+ */
834
+ createShader(type, source) {
835
+ // CRITICAL FIX: Check WebGL context state before shader operations
836
+ if (!this.gl) {
837
+ console.error('❌ Cannot create shader: WebGL context is null');
838
+ if (window.mobileDebug) {
839
+ window.mobileDebug.log(`❌ ${this.canvas?.id}: Cannot create shader - WebGL context is null`);
840
+ }
841
+ return null;
842
+ }
843
+
844
+ if (this.gl.isContextLost()) {
845
+ console.error('❌ Cannot create shader: WebGL context is lost');
846
+ if (window.mobileDebug) {
847
+ window.mobileDebug.log(`❌ ${this.canvas?.id}: Cannot create shader - WebGL context is lost`);
848
+ }
849
+ return null;
850
+ }
851
+
852
+ try {
853
+ const shader = this.gl.createShader(type);
854
+
855
+ if (!shader) {
856
+ console.error('❌ Failed to create shader object - WebGL context may be invalid');
857
+ if (window.mobileDebug) {
858
+ window.mobileDebug.log(`❌ ${this.canvas?.id}: Failed to create shader object`);
859
+ }
860
+ return null;
861
+ }
862
+
863
+ this.gl.shaderSource(shader, source);
864
+ this.gl.compileShader(shader);
865
+
866
+ if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
867
+ const error = this.gl.getShaderInfoLog(shader);
868
+ const shaderType = type === this.gl.VERTEX_SHADER ? 'vertex' : 'fragment';
869
+
870
+ // CRITICAL FIX: Show actual error instead of null
871
+ if (error) {
872
+ console.error(`❌ ${shaderType} shader compilation failed:`, error);
873
+ } else {
874
+ console.error(`❌ ${shaderType} shader compilation failed: WebGL returned no error info (context may be invalid)`);
875
+ }
876
+
877
+ console.error('Shader source:', source);
878
+
879
+ if (window.mobileDebug) {
880
+ const errorMsg = error || 'No error info (context may be invalid)';
881
+ window.mobileDebug.log(`❌ ${this.canvas?.id}: ${shaderType} shader compile failed - ${errorMsg}`);
882
+ // Log first few lines of problematic shader for mobile debugging
883
+ const sourceLines = source.split('\n').slice(0, 5).join('\\n');
884
+ window.mobileDebug.log(`🔍 ${shaderType} shader source start: ${sourceLines}...`);
885
+ }
886
+
887
+ this.gl.deleteShader(shader);
888
+ return null;
889
+ } else {
890
+ if (window.mobileDebug) {
891
+ const shaderType = type === this.gl.VERTEX_SHADER ? 'vertex' : 'fragment';
892
+ window.mobileDebug.log(`✅ ${this.canvas?.id}: ${shaderType} shader compiled successfully`);
893
+ }
894
+ }
895
+
896
+ return shader;
897
+ } catch (error) {
898
+ console.error('❌ Exception during shader creation:', error);
899
+ if (window.mobileDebug) {
900
+ window.mobileDebug.log(`❌ ${this.canvas?.id}: Exception during shader creation - ${error.message}`);
901
+ }
902
+ return null;
903
+ }
904
+ }
905
+
906
+ /**
907
+ * Initialize vertex buffers
908
+ */
909
+ initBuffers() {
910
+ const positions = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
911
+
912
+ this.buffer = this.gl.createBuffer();
913
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);
914
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, positions, this.gl.STATIC_DRAW);
915
+
916
+ const positionLocation = this.gl.getAttribLocation(this.program, 'a_position');
917
+ this.gl.enableVertexAttribArray(positionLocation);
918
+ this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 0, 0);
919
+ }
920
+
921
+ /**
922
+ * Resize canvas and viewport
923
+ */
924
+ resize() {
925
+ // Mobile-optimized canvas sizing
926
+ const dpr = Math.min(window.devicePixelRatio || 1, 2); // Cap at 2x for mobile performance
927
+ const width = this.canvas.clientWidth;
928
+ const height = this.canvas.clientHeight;
929
+
930
+ // Mobile debug: Check for zero dimensions that would cause invisible rendering
931
+ if (window.mobileDebug && (width === 0 || height === 0) && !this._zeroDimWarned) {
932
+ window.mobileDebug.log(`⚠️ ${this.canvas?.id}: Canvas clientWidth=${width}, clientHeight=${height} - will be invisible`);
933
+ this._zeroDimWarned = true;
934
+ }
935
+
936
+ // Only resize if dimensions actually changed (mobile optimization)
937
+ if (this.canvas.width !== width * dpr || this.canvas.height !== height * dpr) {
938
+ this.canvas.width = width * dpr;
939
+ this.canvas.height = height * dpr;
940
+ this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
941
+
942
+ // Mobile debug: Log final canvas dimensions
943
+ if (window.mobileDebug && !this._finalSizeLogged) {
944
+ window.mobileDebug.log(`📐 ${this.canvas?.id}: Final canvas buffer ${this.canvas.width}x${this.canvas.height} (DPR=${dpr})`);
945
+ this._finalSizeLogged = true;
946
+ }
947
+ }
948
+ }
949
+
950
+ /**
951
+ * Show user-friendly WebGL error message
952
+ */
953
+ showWebGLError() {
954
+ if (!this.canvas) return;
955
+ const ctx = this.canvas.getContext('2d');
956
+ if (ctx) {
957
+ ctx.fillStyle = '#000';
958
+ ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
959
+ ctx.fillStyle = '#64ff96';
960
+ ctx.font = '16px Orbitron, monospace';
961
+ ctx.textAlign = 'center';
962
+ ctx.fillText('WebGL Required', this.canvas.width / 2, this.canvas.height / 2);
963
+ ctx.fillStyle = '#888';
964
+ ctx.font = '12px Orbitron, monospace';
965
+ ctx.fillText('Please enable WebGL in your browser', this.canvas.width / 2, this.canvas.height / 2 + 25);
966
+ }
967
+ }
968
+
969
+ /**
970
+ * Update visualization parameters with immediate GPU sync
971
+ */
972
+ updateParameters(params) {
973
+ if (!params || typeof params !== 'object') return;
974
+ // Filter to only finite numbers to prevent NaN/Infinity reaching GPU uniforms
975
+ for (const [key, value] of Object.entries(params)) {
976
+ if (typeof value === 'number' && Number.isFinite(value)) {
977
+ this.params[key] = value;
978
+ }
979
+ }
980
+ // Don't call render() here - engine will call it to prevent infinite loop
981
+ }
982
+
983
+ /**
984
+ * Update mouse interaction state
985
+ */
986
+ updateInteraction(x, y, intensity) {
987
+ this.mouseX = x;
988
+ this.mouseY = y;
989
+ this.mouseIntensity = intensity;
990
+ }
991
+
992
+ /**
993
+ * Render frame
994
+ */
995
+ render() {
996
+ if (!this.program || this._contextLost) return;
997
+ if (!this.gl || this.gl.isContextLost()) {
998
+ this._contextLost = true;
999
+ return;
1000
+ }
1001
+
1002
+ this.resize();
1003
+ this.gl.useProgram(this.program);
1004
+
1005
+ // CRITICAL FIX: Clear framebuffer before rendering
1006
+ this.gl.clearColor(0.0, 0.0, 0.0, 0.0);
1007
+ this.gl.clear(this.gl.COLOR_BUFFER_BIT);
1008
+
1009
+ // Mobile optimization: Log render parameters once per canvas (console only)
1010
+ if (!this._renderParamsLogged) {
1011
+ console.log(`[Mobile] ${this.canvas?.id}: Render params - geometry=${this.params.geometry}, gridDensity=${this.params.gridDensity}, intensity=${this.params.intensity}`);
1012
+ this._renderParamsLogged = true;
1013
+ }
1014
+
1015
+ // Role-specific intensity for quantum effects
1016
+ const roleIntensities = {
1017
+ 'background': 0.4,
1018
+ 'shadow': 0.6,
1019
+ 'content': 1.0,
1020
+ 'highlight': 1.3,
1021
+ 'accent': 1.6
1022
+ };
1023
+
1024
+ const time = Date.now() - this.startTime;
1025
+
1026
+ // Set uniforms
1027
+ this.gl.uniform2f(this.uniforms.resolution, this.canvas.width, this.canvas.height);
1028
+ this.gl.uniform1f(this.uniforms.time, time);
1029
+ this.gl.uniform2f(this.uniforms.mouse, this.mouseX, this.mouseY);
1030
+ this.gl.uniform1f(this.uniforms.geometry, this.params.geometry);
1031
+ // 🎵 QUANTUM AUDIO REACTIVITY - Direct and effective
1032
+ let gridDensity = this.params.gridDensity;
1033
+ let morphFactor = this.params.morphFactor;
1034
+ let hue = this.params.hue;
1035
+ let chaos = this.params.chaos;
1036
+
1037
+ if (window.audioEnabled && window.audioReactive) {
1038
+ // Quantum audio mapping: Enhanced complex lattice response
1039
+ gridDensity += window.audioReactive.bass * 40; // Bass creates dense lattice structures
1040
+ morphFactor += window.audioReactive.mid * 1.2; // Mid frequencies morph the geometry
1041
+ hue += window.audioReactive.high * 120; // High frequencies shift colors dramatically
1042
+ chaos += window.audioReactive.energy * 0.6; // Overall energy adds chaos/complexity
1043
+
1044
+ // Debug logging every 10 seconds to verify audio reactivity is working
1045
+ if (Date.now() % 10000 < 16) {
1046
+ console.log(`🌌 Quantum audio reactivity: Density+${(window.audioReactive.bass * 40).toFixed(1)} Morph+${(window.audioReactive.mid * 1.2).toFixed(2)} Hue+${(window.audioReactive.high * 120).toFixed(1)} Chaos+${(window.audioReactive.energy * 0.6).toFixed(2)}`);
1047
+ }
1048
+ }
1049
+
1050
+ this.gl.uniform1f(this.uniforms.gridDensity, Math.min(100, gridDensity));
1051
+ this.gl.uniform1f(this.uniforms.morphFactor, Math.min(2, morphFactor));
1052
+ this.gl.uniform1f(this.uniforms.chaos, Math.min(1, chaos));
1053
+ this.gl.uniform1f(this.uniforms.speed, this.params.speed);
1054
+ // Hue passed as normalized 0-1 for HSL color control
1055
+ this.gl.uniform1f(this.uniforms.hue, (hue % 360) / 360.0);
1056
+ this.gl.uniform1f(this.uniforms.intensity, this.params.intensity);
1057
+ this.gl.uniform1f(this.uniforms.saturation, this.params.saturation);
1058
+ this.gl.uniform1f(this.uniforms.dimension, this.params.dimension);
1059
+ this.gl.uniform1f(this.uniforms.rot4dXY, this.params.rot4dXY || 0.0);
1060
+ this.gl.uniform1f(this.uniforms.rot4dXZ, this.params.rot4dXZ || 0.0);
1061
+ this.gl.uniform1f(this.uniforms.rot4dYZ, this.params.rot4dYZ || 0.0);
1062
+ this.gl.uniform1f(this.uniforms.rot4dXW, this.params.rot4dXW || 0.0);
1063
+ this.gl.uniform1f(this.uniforms.rot4dYW, this.params.rot4dYW || 0.0);
1064
+ this.gl.uniform1f(this.uniforms.rot4dZW, this.params.rot4dZW || 0.0);
1065
+ this.gl.uniform1f(this.uniforms.mouseIntensity, this.mouseIntensity);
1066
+ this.gl.uniform1f(this.uniforms.clickIntensity, this.clickIntensity);
1067
+ this.gl.uniform1f(this.uniforms.roleIntensity, roleIntensities[this.role] || 1.0);
1068
+
1069
+ this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
1070
+ }
1071
+
1072
+ // Audio reactivity now handled directly in render() loop - no complex methods needed
1073
+
1074
+ /**
1075
+ * Clean up WebGL resources
1076
+ */
1077
+ destroy() {
1078
+ // Remove context loss listeners
1079
+ if (this.canvas) {
1080
+ if (this._onContextLost) {
1081
+ this.canvas.removeEventListener('webglcontextlost', this._onContextLost);
1082
+ }
1083
+ if (this._onContextRestored) {
1084
+ this.canvas.removeEventListener('webglcontextrestored', this._onContextRestored);
1085
+ }
1086
+ }
1087
+
1088
+ // Clean up WebGL resources (guard against lost context)
1089
+ if (this.gl && !this.gl.isContextLost()) {
1090
+ if (this.program) {
1091
+ this.gl.deleteProgram(this.program);
1092
+ }
1093
+ if (this.buffer) {
1094
+ this.gl.deleteBuffer(this.buffer);
1095
+ }
1096
+ }
1097
+
1098
+ this.program = null;
1099
+ this.buffer = null;
1100
+ this.gl = null;
1101
+ this._contextLost = true;
1102
+ }
1103
+ }