@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,496 @@
1
+ /**
2
+ * UnifiedRenderBridge - Connects VIB3+ visualization systems to WebGL/WebGPU backends.
3
+ *
4
+ * All three VIB3+ visualization systems (Quantum, Faceted, Holographic) use the same
5
+ * rendering pattern: procedural fragment shaders on a fullscreen quad. This bridge
6
+ * abstracts that pattern so systems can render identically on either backend.
7
+ *
8
+ * Usage:
9
+ * const bridge = await UnifiedRenderBridge.create(canvas, { preferWebGPU: true });
10
+ * bridge.compileShader('faceted', vertexSrc, fragmentSrc);
11
+ * bridge.setUniforms({ u_time: 1.5, u_resolution: [800, 600], ... });
12
+ * bridge.render('faceted');
13
+ * bridge.dispose();
14
+ */
15
+
16
+ import { createWebGPUBackend, isWebGPUSupported, WGSLShaderLib } from './backends/WebGPUBackend.js';
17
+
18
+ /** @typedef {'webgl'|'webgpu'} BackendType */
19
+
20
+ /**
21
+ * Packs VIB3+ parameters into a Float32Array for WebGPU uniform buffer.
22
+ * Layout must match VIB3Uniforms struct in WGSL.
23
+ *
24
+ * @param {object} uniforms - Uniform name→value map
25
+ * @returns {Float32Array}
26
+ */
27
+ function packVIB3Uniforms(uniforms) {
28
+ // Total: 32 floats = 128 bytes → aligned to 256 bytes in buffer
29
+ const data = new Float32Array(64); // 256 bytes
30
+
31
+ data[0] = uniforms.u_time || 0;
32
+ data[1] = 0; // _pad0
33
+ data[2] = uniforms.u_resolution?.[0] || 800;
34
+ data[3] = uniforms.u_resolution?.[1] || 600;
35
+
36
+ data[4] = uniforms.u_geometry || 0;
37
+ data[5] = uniforms.u_rot4dXY || 0;
38
+ data[6] = uniforms.u_rot4dXZ || 0;
39
+ data[7] = uniforms.u_rot4dYZ || 0;
40
+ data[8] = uniforms.u_rot4dXW || 0;
41
+ data[9] = uniforms.u_rot4dYW || 0;
42
+ data[10] = uniforms.u_rot4dZW || 0;
43
+
44
+ data[11] = uniforms.u_dimension || 3.5;
45
+ data[12] = uniforms.u_gridDensity || 1.5;
46
+ data[13] = uniforms.u_morphFactor || 1.0;
47
+ data[14] = uniforms.u_chaos || 0.2;
48
+ data[15] = uniforms.u_speed || 1.0;
49
+ data[16] = uniforms.u_hue || 200;
50
+ data[17] = uniforms.u_intensity || 0.7;
51
+ data[18] = uniforms.u_saturation || 0.8;
52
+
53
+ data[19] = uniforms.u_mouseIntensity || 0;
54
+ data[20] = uniforms.u_clickIntensity || 0;
55
+ data[21] = uniforms.u_bass || 0;
56
+ data[22] = uniforms.u_mid || 0;
57
+ data[23] = uniforms.u_high || 0;
58
+
59
+ data[24] = uniforms.u_layerScale || 1.0;
60
+ data[25] = uniforms.u_layerOpacity || 1.0;
61
+ data[26] = 0; // _pad1
62
+ data[27] = uniforms.u_layerColor?.[0] || 1.0;
63
+ data[28] = uniforms.u_layerColor?.[1] || 1.0;
64
+ data[29] = uniforms.u_layerColor?.[2] || 1.0;
65
+ data[30] = uniforms.u_densityMult || 1.0;
66
+ data[31] = uniforms.u_speedMult || 1.0;
67
+ // [32..63] padding to 256
68
+
69
+ return data;
70
+ }
71
+
72
+ export class UnifiedRenderBridge {
73
+ /**
74
+ * @param {HTMLCanvasElement} canvas
75
+ * @param {BackendType} backendType
76
+ * @param {object} backend - WebGLBackend-like or WebGPUBackend instance
77
+ */
78
+ constructor(canvas, backendType, backend) {
79
+ /** @type {HTMLCanvasElement} */
80
+ this.canvas = canvas;
81
+
82
+ /** @type {BackendType} */
83
+ this.backendType = backendType;
84
+
85
+ /** @type {object} */
86
+ this.backend = backend;
87
+
88
+ // ---- WebGL state ----
89
+ /** @type {Map<string, {program: WebGLProgram, uniformLocations: Map<string, WebGLUniformLocation>}>} */
90
+ this._glPrograms = new Map();
91
+
92
+ /** @type {WebGLBuffer|null} */
93
+ this._glQuadBuffer = null;
94
+
95
+ // ---- WebGPU state ----
96
+ /** @type {Map<string, string>} pipeline name → buffer name */
97
+ this._gpuPipelineBuffers = new Map();
98
+
99
+ // ---- Shared state ----
100
+ /** @type {Map<string, object>} */
101
+ this._currentUniforms = new Map();
102
+
103
+ this._initialized = false;
104
+ }
105
+
106
+ /**
107
+ * Create a UnifiedRenderBridge with automatic backend selection.
108
+ *
109
+ * @param {HTMLCanvasElement} canvas - Target canvas element
110
+ * @param {object} [options]
111
+ * @param {boolean} [options.preferWebGPU=true] - Try WebGPU first
112
+ * @param {boolean} [options.debug=false] - Enable debug logging
113
+ * @returns {Promise<UnifiedRenderBridge>}
114
+ */
115
+ static async create(canvas, options = {}) {
116
+ const preferWebGPU = options.preferWebGPU !== false;
117
+ const debug = options.debug || false;
118
+
119
+ // Try WebGPU first if preferred
120
+ if (preferWebGPU && isWebGPUSupported()) {
121
+ try {
122
+ const gpuBackend = await createWebGPUBackend(canvas, {
123
+ debug,
124
+ depth: false // Procedural shaders don't need depth
125
+ });
126
+
127
+ if (gpuBackend) {
128
+ const bridge = new UnifiedRenderBridge(canvas, 'webgpu', gpuBackend);
129
+ bridge._initialized = true;
130
+ if (debug) console.log('UnifiedRenderBridge: using WebGPU backend');
131
+ return bridge;
132
+ }
133
+ } catch (e) {
134
+ if (debug) console.warn('WebGPU init failed, falling back to WebGL:', e);
135
+ }
136
+ }
137
+
138
+ // Fall back to WebGL
139
+ const gl = canvas.getContext('webgl2') || canvas.getContext('webgl');
140
+ if (!gl) {
141
+ throw new Error('Neither WebGPU nor WebGL is available');
142
+ }
143
+
144
+ const bridge = new UnifiedRenderBridge(canvas, 'webgl', gl);
145
+ bridge._initWebGLQuadBuffer();
146
+ bridge._initialized = true;
147
+ if (debug) console.log('UnifiedRenderBridge: using WebGL backend');
148
+ return bridge;
149
+ }
150
+
151
+ /**
152
+ * Get the active backend type
153
+ * @returns {BackendType}
154
+ */
155
+ getBackendType() {
156
+ return this.backendType;
157
+ }
158
+
159
+ /**
160
+ * Check if the bridge is initialized
161
+ * @returns {boolean}
162
+ */
163
+ get initialized() {
164
+ return this._initialized;
165
+ }
166
+
167
+ // ========================================================================
168
+ // Shader Compilation
169
+ // ========================================================================
170
+
171
+ /**
172
+ * Compile a shader program for a named visualization.
173
+ *
174
+ * For WebGL: compiles GLSL vertex + fragment shaders.
175
+ * For WebGPU: compiles WGSL fragment shader with fullscreen pipeline.
176
+ *
177
+ * @param {string} name - Shader name (e.g., 'faceted', 'quantum')
178
+ * @param {object} sources
179
+ * @param {string} sources.glslVertex - GLSL vertex shader source
180
+ * @param {string} sources.glslFragment - GLSL fragment shader source
181
+ * @param {string} [sources.wgslFragment] - WGSL fragment shader source (optional, for WebGPU)
182
+ * @returns {boolean} Success
183
+ */
184
+ compileShader(name, sources) {
185
+ if (this.backendType === 'webgl') {
186
+ return this._compileWebGLShader(name, sources.glslVertex, sources.glslFragment);
187
+ } else {
188
+ if (!sources.wgslFragment) {
189
+ // If no WGSL provided, we can't render on WebGPU with this shader.
190
+ // Systems that want WebGPU support must provide WGSL sources.
191
+ console.warn(`No WGSL fragment shader for "${name}", WebGPU rendering unavailable`);
192
+ return false;
193
+ }
194
+ return this._compileWebGPUShader(name, sources.wgslFragment);
195
+ }
196
+ }
197
+
198
+ /**
199
+ * @private
200
+ */
201
+ _compileWebGLShader(name, vertexSrc, fragmentSrc) {
202
+ const gl = this.backend;
203
+
204
+ const vertexShader = this._compileGLShader(gl, gl.VERTEX_SHADER, vertexSrc);
205
+ const fragmentShader = this._compileGLShader(gl, gl.FRAGMENT_SHADER, fragmentSrc);
206
+
207
+ if (!vertexShader || !fragmentShader) return false;
208
+
209
+ const program = gl.createProgram();
210
+ gl.attachShader(program, vertexShader);
211
+ gl.attachShader(program, fragmentShader);
212
+ gl.linkProgram(program);
213
+
214
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
215
+ console.error(`Shader link error [${name}]:`, gl.getProgramInfoLog(program));
216
+ return false;
217
+ }
218
+
219
+ // Cache uniform locations
220
+ const uniformLocations = new Map();
221
+ const numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
222
+ for (let i = 0; i < numUniforms; i++) {
223
+ const info = gl.getActiveUniform(program, i);
224
+ if (info) {
225
+ uniformLocations.set(info.name, gl.getUniformLocation(program, info.name));
226
+ }
227
+ }
228
+
229
+ // Clean up old program if replacing
230
+ const old = this._glPrograms.get(name);
231
+ if (old) {
232
+ gl.deleteProgram(old.program);
233
+ }
234
+
235
+ this._glPrograms.set(name, { program, uniformLocations });
236
+
237
+ // Clean up shader objects (they're linked into the program now)
238
+ gl.deleteShader(vertexShader);
239
+ gl.deleteShader(fragmentShader);
240
+
241
+ return true;
242
+ }
243
+
244
+ /**
245
+ * @private
246
+ */
247
+ _compileGLShader(gl, type, source) {
248
+ const shader = gl.createShader(type);
249
+ gl.shaderSource(shader, source);
250
+ gl.compileShader(shader);
251
+
252
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
253
+ console.error('Shader compile error:', gl.getShaderInfoLog(shader));
254
+ gl.deleteShader(shader);
255
+ return null;
256
+ }
257
+
258
+ return shader;
259
+ }
260
+
261
+ /**
262
+ * @private
263
+ */
264
+ _compileWebGPUShader(name, wgslFragmentSrc) {
265
+ const gpu = this.backend;
266
+
267
+ // Create custom uniform buffer for VIB3+ uniforms
268
+ const bufferName = `${name}-uniforms`;
269
+ const existing = gpu.getCustomUniformBuffer(bufferName);
270
+ if (!existing) {
271
+ gpu.createCustomUniformBuffer(bufferName, 256);
272
+ }
273
+
274
+ const uniformEntry = gpu.getCustomUniformBuffer(bufferName);
275
+
276
+ // Create fullscreen pipeline with the custom bind group layout
277
+ try {
278
+ gpu.createFullscreenPipeline(name, wgslFragmentSrc, {
279
+ bindGroupLayouts: [uniformEntry.layout]
280
+ });
281
+
282
+ this._gpuPipelineBuffers.set(name, bufferName);
283
+ return true;
284
+ } catch (e) {
285
+ console.error(`WebGPU pipeline creation failed [${name}]:`, e);
286
+ return false;
287
+ }
288
+ }
289
+
290
+ // ========================================================================
291
+ // Uniform Updates
292
+ // ========================================================================
293
+
294
+ /**
295
+ * Set uniforms for the next render call.
296
+ * Accepts a flat object with uniform names as keys.
297
+ *
298
+ * @param {object} uniforms - e.g., { u_time: 1.5, u_resolution: [800, 600] }
299
+ */
300
+ setUniforms(uniforms) {
301
+ // Store for render-time application
302
+ this._pendingUniforms = uniforms;
303
+ }
304
+
305
+ // ========================================================================
306
+ // Rendering
307
+ // ========================================================================
308
+
309
+ /**
310
+ * Render a fullscreen quad using the named shader program.
311
+ *
312
+ * @param {string} name - Shader name to use
313
+ * @param {object} [options]
314
+ * @param {number[]} [options.clearColor] - RGBA 0-1
315
+ * @param {boolean} [options.clear] - Whether to clear before drawing
316
+ */
317
+ render(name, options = {}) {
318
+ if (this.backendType === 'webgl') {
319
+ this._renderWebGL(name, options);
320
+ } else {
321
+ this._renderWebGPU(name, options);
322
+ }
323
+ }
324
+
325
+ /**
326
+ * @private
327
+ */
328
+ _renderWebGL(name, options) {
329
+ const gl = this.backend;
330
+ const entry = this._glPrograms.get(name);
331
+ if (!entry) return;
332
+
333
+ const { program, uniformLocations } = entry;
334
+
335
+ gl.useProgram(program);
336
+ gl.enable(gl.BLEND);
337
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
338
+
339
+ if (options.clear !== false) {
340
+ const cc = options.clearColor || [0, 0, 0, 1];
341
+ gl.clearColor(cc[0], cc[1], cc[2], cc[3]);
342
+ gl.clear(gl.COLOR_BUFFER_BIT);
343
+ }
344
+
345
+ // Apply uniforms
346
+ const uniforms = this._pendingUniforms || {};
347
+ for (const [uName, value] of Object.entries(uniforms)) {
348
+ const loc = uniformLocations.get(uName);
349
+ if (loc === null || loc === undefined) continue;
350
+
351
+ if (Array.isArray(value)) {
352
+ switch (value.length) {
353
+ case 2: gl.uniform2fv(loc, value); break;
354
+ case 3: gl.uniform3fv(loc, value); break;
355
+ case 4: gl.uniform4fv(loc, value); break;
356
+ default: gl.uniform1fv(loc, value); break;
357
+ }
358
+ } else if (typeof value === 'number') {
359
+ gl.uniform1f(loc, value);
360
+ } else if (typeof value === 'boolean') {
361
+ gl.uniform1i(loc, value ? 1 : 0);
362
+ }
363
+ }
364
+
365
+ // Draw fullscreen quad
366
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._glQuadBuffer);
367
+ const posLoc = gl.getAttribLocation(program, 'a_position');
368
+ if (posLoc >= 0) {
369
+ gl.enableVertexAttribArray(posLoc);
370
+ gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0);
371
+ }
372
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
373
+ }
374
+
375
+ /**
376
+ * @private
377
+ */
378
+ _renderWebGPU(name, options) {
379
+ const gpu = this.backend;
380
+ const bufferName = this._gpuPipelineBuffers.get(name);
381
+ if (!bufferName) return;
382
+
383
+ const uniformEntry = gpu.getCustomUniformBuffer(bufferName);
384
+ if (!uniformEntry) return;
385
+
386
+ // Pack and upload uniforms
387
+ const packed = packVIB3Uniforms(this._pendingUniforms || {});
388
+ gpu.updateCustomUniforms(bufferName, packed);
389
+
390
+ // Render fullscreen quad
391
+ gpu.renderFullscreenQuad({
392
+ pipeline: name,
393
+ bindGroups: [uniformEntry.bindGroup],
394
+ clearColor: options.clearColor || [0, 0, 0, 1],
395
+ clear: options.clear !== false
396
+ });
397
+ }
398
+
399
+ // ========================================================================
400
+ // Canvas Management
401
+ // ========================================================================
402
+
403
+ /**
404
+ * Resize the rendering surface
405
+ * @param {number} width
406
+ * @param {number} height
407
+ * @param {number} [pixelRatio=1]
408
+ */
409
+ resize(width, height, pixelRatio = 1) {
410
+ const w = Math.floor(width * pixelRatio);
411
+ const h = Math.floor(height * pixelRatio);
412
+
413
+ this.canvas.width = w;
414
+ this.canvas.height = h;
415
+
416
+ if (this.backendType === 'webgl') {
417
+ this.backend.viewport(0, 0, w, h);
418
+ } else {
419
+ this.backend.resize(w, h);
420
+ }
421
+ }
422
+
423
+ /**
424
+ * Get the raw WebGL context or WebGPU backend for advanced usage
425
+ * @returns {WebGLRenderingContext|WebGL2RenderingContext|import('./backends/WebGPUBackend.js').WebGPUBackend}
426
+ */
427
+ getRawBackend() {
428
+ return this.backend;
429
+ }
430
+
431
+ // ========================================================================
432
+ // Cleanup
433
+ // ========================================================================
434
+
435
+ /**
436
+ * Dispose of all resources
437
+ */
438
+ dispose() {
439
+ if (this.backendType === 'webgl') {
440
+ const gl = this.backend;
441
+ for (const [, entry] of this._glPrograms) {
442
+ gl.deleteProgram(entry.program);
443
+ }
444
+ this._glPrograms.clear();
445
+
446
+ if (this._glQuadBuffer) {
447
+ gl.deleteBuffer(this._glQuadBuffer);
448
+ this._glQuadBuffer = null;
449
+ }
450
+
451
+ // Lose context to free GPU memory
452
+ const loseContext = gl.getExtension('WEBGL_lose_context');
453
+ if (loseContext) {
454
+ loseContext.loseContext();
455
+ }
456
+ } else {
457
+ this.backend.dispose();
458
+ }
459
+
460
+ this._gpuPipelineBuffers.clear();
461
+ this._currentUniforms.clear();
462
+ this._pendingUniforms = null;
463
+ this._initialized = false;
464
+ }
465
+
466
+ // ========================================================================
467
+ // Internal Helpers
468
+ // ========================================================================
469
+
470
+ /**
471
+ * Create the fullscreen quad vertex buffer for WebGL
472
+ * @private
473
+ */
474
+ _initWebGLQuadBuffer() {
475
+ const gl = this.backend;
476
+ const vertices = new Float32Array([
477
+ -1, -1, 1, -1, -1, 1,
478
+ -1, 1, 1, -1, 1, 1
479
+ ]);
480
+ this._glQuadBuffer = gl.createBuffer();
481
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._glQuadBuffer);
482
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
483
+ }
484
+ }
485
+
486
+ /**
487
+ * Check if WebGPU is available in the current environment
488
+ * @returns {boolean}
489
+ */
490
+ export function canUseWebGPU() {
491
+ return isWebGPUSupported();
492
+ }
493
+
494
+ export { WGSLShaderLib };
495
+
496
+ export default UnifiedRenderBridge;