@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.
- package/CHANGELOG.md +118 -0
- package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +34 -0
- package/DOCS/CI_TESTING.md +38 -0
- package/DOCS/CLI_ONBOARDING.md +75 -0
- package/DOCS/CONTROL_REFERENCE.md +64 -0
- package/DOCS/DEV_TRACK_ANALYSIS.md +77 -0
- package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +42 -0
- package/DOCS/DEV_TRACK_SESSION_2026-01-31.md +220 -0
- package/DOCS/ENV_SETUP.md +189 -0
- package/DOCS/EXPORT_FORMATS.md +417 -0
- package/DOCS/GPU_DISPOSAL_GUIDE.md +21 -0
- package/DOCS/LICENSING_TIERS.md +275 -0
- package/DOCS/MASTER_PLAN_2026-01-31.md +570 -0
- package/DOCS/OBS_SETUP_GUIDE.md +98 -0
- package/DOCS/PROJECT_SETUP.md +66 -0
- package/DOCS/RENDERER_LIFECYCLE.md +40 -0
- package/DOCS/REPO_MANIFEST.md +121 -0
- package/DOCS/SESSION_014_PLAN.md +195 -0
- package/DOCS/SESSION_LOG_2026-01-07.md +56 -0
- package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +72 -0
- package/DOCS/SYSTEM_AUDIT_2026-01-30.md +738 -0
- package/DOCS/SYSTEM_INVENTORY.md +520 -0
- package/DOCS/TELEMETRY_EXPORTS.md +34 -0
- package/DOCS/WEBGPU_STATUS.md +38 -0
- package/DOCS/XR_BENCHMARKS.md +608 -0
- package/LICENSE +21 -0
- package/README.md +426 -0
- package/docs/.nojekyll +0 -0
- package/docs/01-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/02-hyperspatial_ego_death.html +346 -0
- package/docs/03-post_cartesian_sublime.html +346 -0
- package/docs/04-crystalline_void_meditation.html +346 -0
- package/docs/05-quantum_decoherence_ballet.html +346 -0
- package/docs/06-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/07-hyperspatial_ego_death.html +346 -0
- package/docs/08-post_cartesian_sublime.html +346 -0
- package/docs/09-crystalline_void_meditation.html +346 -0
- package/docs/10-quantum_decoherence_ballet.html +346 -0
- package/docs/11-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/12-hyperspatial_ego_death.html +346 -0
- package/docs/13-post_cartesian_sublime.html +346 -0
- package/docs/index.html +794 -0
- package/docs/test-hub.html +441 -0
- package/docs/url-state.js +102 -0
- package/docs/vib3-exports/01-quantum-quantum-tetrahedron-lattice.html +489 -0
- package/docs/vib3-exports/02-quantum-quantum-hypersphere-matrix.html +489 -0
- package/docs/vib3-exports/03-quantum-quantum-hypertetra-fractal.html +489 -0
- package/docs/vib3-exports/04-faceted-faceted-crystal-structure.html +407 -0
- package/docs/vib3-exports/05-faceted-faceted-klein-bottle.html +407 -0
- package/docs/vib3-exports/06-faceted-faceted-hypertetra-torus.html +407 -0
- package/docs/vib3-exports/07-holographic-holographic-wave-field.html +457 -0
- package/docs/vib3-exports/08-holographic-holographic-hypersphere-sphere.html +457 -0
- package/docs/vib3-exports/09-holographic-holographic-hypertetra-crystal.html +457 -0
- package/docs/vib3-exports/index.html +238 -0
- package/docs/webgpu-live.html +702 -0
- package/package.json +367 -0
- package/src/advanced/AIPresetGenerator.js +777 -0
- package/src/advanced/MIDIController.js +703 -0
- package/src/advanced/OffscreenWorker.js +1051 -0
- package/src/advanced/WebGPUCompute.js +1051 -0
- package/src/advanced/WebXRRenderer.js +680 -0
- package/src/agent/cli/AgentCLI.js +615 -0
- package/src/agent/cli/index.js +14 -0
- package/src/agent/index.js +73 -0
- package/src/agent/mcp/MCPServer.js +950 -0
- package/src/agent/mcp/index.js +9 -0
- package/src/agent/mcp/tools.js +548 -0
- package/src/agent/telemetry/EventStream.js +669 -0
- package/src/agent/telemetry/Instrumentation.js +618 -0
- package/src/agent/telemetry/TelemetryExporters.js +427 -0
- package/src/agent/telemetry/TelemetryService.js +464 -0
- package/src/agent/telemetry/index.js +52 -0
- package/src/benchmarks/BenchmarkRunner.js +381 -0
- package/src/benchmarks/MetricsCollector.js +299 -0
- package/src/benchmarks/index.js +9 -0
- package/src/benchmarks/scenes.js +259 -0
- package/src/cli/index.js +675 -0
- package/src/config/ApiConfig.js +88 -0
- package/src/core/CanvasManager.js +217 -0
- package/src/core/ErrorReporter.js +117 -0
- package/src/core/ParameterMapper.js +333 -0
- package/src/core/Parameters.js +396 -0
- package/src/core/RendererContracts.js +200 -0
- package/src/core/UnifiedResourceManager.js +370 -0
- package/src/core/VIB3Engine.js +636 -0
- package/src/core/renderers/FacetedRendererAdapter.js +32 -0
- package/src/core/renderers/HolographicRendererAdapter.js +29 -0
- package/src/core/renderers/QuantumRendererAdapter.js +29 -0
- package/src/core/renderers/RendererLifecycleManager.js +63 -0
- package/src/creative/ColorPresetsSystem.js +980 -0
- package/src/creative/ParameterTimeline.js +1061 -0
- package/src/creative/PostProcessingPipeline.js +1113 -0
- package/src/creative/TransitionAnimator.js +683 -0
- package/src/export/CSSExporter.js +226 -0
- package/src/export/CardGeneratorBase.js +279 -0
- package/src/export/ExportManager.js +580 -0
- package/src/export/FacetedCardGenerator.js +279 -0
- package/src/export/HolographicCardGenerator.js +543 -0
- package/src/export/LottieExporter.js +552 -0
- package/src/export/QuantumCardGenerator.js +315 -0
- package/src/export/SVGExporter.js +519 -0
- package/src/export/ShaderExporter.js +903 -0
- package/src/export/TradingCardGenerator.js +3055 -0
- package/src/export/TradingCardManager.js +181 -0
- package/src/export/VIB3PackageExporter.js +559 -0
- package/src/export/index.js +14 -0
- package/src/export/systems/TradingCardSystemFaceted.js +494 -0
- package/src/export/systems/TradingCardSystemHolographic.js +452 -0
- package/src/export/systems/TradingCardSystemQuantum.js +411 -0
- package/src/faceted/FacetedSystem.js +963 -0
- package/src/features/CollectionManager.js +433 -0
- package/src/gallery/CollectionManager.js +240 -0
- package/src/gallery/GallerySystem.js +485 -0
- package/src/geometry/GeometryFactory.js +314 -0
- package/src/geometry/GeometryLibrary.js +72 -0
- package/src/geometry/buffers/BufferBuilder.js +338 -0
- package/src/geometry/buffers/index.js +18 -0
- package/src/geometry/generators/Crystal.js +420 -0
- package/src/geometry/generators/Fractal.js +298 -0
- package/src/geometry/generators/KleinBottle.js +197 -0
- package/src/geometry/generators/Sphere.js +192 -0
- package/src/geometry/generators/Tesseract.js +160 -0
- package/src/geometry/generators/Tetrahedron.js +225 -0
- package/src/geometry/generators/Torus.js +304 -0
- package/src/geometry/generators/Wave.js +341 -0
- package/src/geometry/index.js +142 -0
- package/src/geometry/warp/HypersphereCore.js +211 -0
- package/src/geometry/warp/HypertetraCore.js +386 -0
- package/src/geometry/warp/index.js +57 -0
- package/src/holograms/HolographicVisualizer.js +1073 -0
- package/src/holograms/RealHolographicSystem.js +966 -0
- package/src/holograms/variantRegistry.js +69 -0
- package/src/integrations/FigmaPlugin.js +854 -0
- package/src/integrations/OBSMode.js +754 -0
- package/src/integrations/ThreeJsPackage.js +660 -0
- package/src/integrations/TouchDesignerExport.js +552 -0
- package/src/integrations/frameworks/Vib3React.js +591 -0
- package/src/integrations/frameworks/Vib3Svelte.js +654 -0
- package/src/integrations/frameworks/Vib3Vue.js +628 -0
- package/src/llm/LLMParameterInterface.js +240 -0
- package/src/llm/LLMParameterUI.js +577 -0
- package/src/math/Mat4x4.js +708 -0
- package/src/math/Projection.js +341 -0
- package/src/math/Rotor4D.js +637 -0
- package/src/math/Vec4.js +476 -0
- package/src/math/constants.js +164 -0
- package/src/math/index.js +68 -0
- package/src/math/projections.js +54 -0
- package/src/math/rotations.js +196 -0
- package/src/quantum/QuantumEngine.js +906 -0
- package/src/quantum/QuantumVisualizer.js +1103 -0
- package/src/reactivity/ReactivityConfig.js +499 -0
- package/src/reactivity/ReactivityManager.js +586 -0
- package/src/reactivity/SpatialInputSystem.js +1783 -0
- package/src/reactivity/index.js +93 -0
- package/src/render/CommandBuffer.js +465 -0
- package/src/render/MultiCanvasBridge.js +340 -0
- package/src/render/RenderCommand.js +514 -0
- package/src/render/RenderResourceRegistry.js +523 -0
- package/src/render/RenderState.js +552 -0
- package/src/render/RenderTarget.js +512 -0
- package/src/render/ShaderLoader.js +253 -0
- package/src/render/ShaderProgram.js +599 -0
- package/src/render/UnifiedRenderBridge.js +496 -0
- package/src/render/backends/WebGLBackend.js +1108 -0
- package/src/render/backends/WebGPUBackend.js +1409 -0
- package/src/render/commands/CommandBufferExecutor.js +607 -0
- package/src/render/commands/RenderCommandBuffer.js +661 -0
- package/src/render/commands/index.js +17 -0
- package/src/render/index.js +367 -0
- package/src/scene/Disposable.js +498 -0
- package/src/scene/MemoryPool.js +618 -0
- package/src/scene/Node4D.js +697 -0
- package/src/scene/ResourceManager.js +599 -0
- package/src/scene/Scene4D.js +540 -0
- package/src/scene/index.js +98 -0
- package/src/schemas/error.schema.json +84 -0
- package/src/schemas/extension.schema.json +88 -0
- package/src/schemas/index.js +214 -0
- package/src/schemas/parameters.schema.json +142 -0
- package/src/schemas/tool-pack.schema.json +44 -0
- package/src/schemas/tool-response.schema.json +127 -0
- package/src/shaders/common/fullscreen.vert.glsl +5 -0
- package/src/shaders/common/fullscreen.vert.wgsl +17 -0
- package/src/shaders/common/geometry24.glsl +65 -0
- package/src/shaders/common/geometry24.wgsl +54 -0
- package/src/shaders/common/rotation4d.glsl +85 -0
- package/src/shaders/common/rotation4d.wgsl +86 -0
- package/src/shaders/common/uniforms.glsl +44 -0
- package/src/shaders/common/uniforms.wgsl +48 -0
- package/src/shaders/faceted/faceted.frag.glsl +129 -0
- package/src/shaders/faceted/faceted.frag.wgsl +164 -0
- package/src/shaders/holographic/holographic.frag.glsl +406 -0
- package/src/shaders/holographic/holographic.frag.wgsl +185 -0
- package/src/shaders/quantum/quantum.frag.glsl +513 -0
- package/src/shaders/quantum/quantum.frag.wgsl +361 -0
- package/src/testing/ParallelTestFramework.js +519 -0
- package/src/testing/__snapshots__/exportFormats.test.js.snap +24 -0
- package/src/testing/exportFormats.test.js +8 -0
- package/src/testing/projections.test.js +14 -0
- package/src/testing/rotations.test.js +37 -0
- package/src/ui/InteractivityMenu.js +516 -0
- package/src/ui/StatusManager.js +96 -0
- package/src/ui/adaptive/renderers/webgpu/BufferLayout.ts +252 -0
- package/src/ui/adaptive/renderers/webgpu/PolytopeInstanceBuffer.ts +144 -0
- package/src/ui/adaptive/renderers/webgpu/TripleBufferedUniform.ts +170 -0
- package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +735 -0
- package/src/ui/adaptive/renderers/webgpu/index.ts +112 -0
- package/src/variations/VariationManager.js +431 -0
- package/src/viewer/AudioReactivity.js +505 -0
- package/src/viewer/CardBending.js +481 -0
- package/src/viewer/GalleryUI.js +832 -0
- package/src/viewer/ReactivityManager.js +590 -0
- package/src/viewer/TradingCardExporter.js +600 -0
- package/src/viewer/ViewerPortal.js +374 -0
- package/src/viewer/index.js +12 -0
- package/src/wasm/WasmLoader.js +296 -0
- package/src/wasm/index.js +132 -0
- package/tools/agentic/mcpTools.js +88 -0
- package/tools/cli/agent-cli.js +92 -0
- package/tools/export/formats.js +24 -0
- package/tools/math/rotation-baseline.mjs +64 -0
- package/tools/shader-sync-verify.js +937 -0
- package/tools/telemetry/manifestPipeline.js +141 -0
- package/tools/telemetry/telemetryEvents.js +35 -0
- package/types/adaptive-sdk.d.ts +185 -0
- package/types/advanced/AIPresetGenerator.d.ts +81 -0
- package/types/advanced/MIDIController.d.ts +100 -0
- package/types/advanced/OffscreenWorker.d.ts +82 -0
- package/types/advanced/WebGPUCompute.d.ts +52 -0
- package/types/advanced/WebXRRenderer.d.ts +77 -0
- package/types/advanced/index.d.ts +46 -0
- package/types/core/ErrorReporter.d.ts +50 -0
- package/types/core/VIB3Engine.d.ts +204 -0
- package/types/creative/ColorPresetsSystem.d.ts +91 -0
- package/types/creative/ParameterTimeline.d.ts +74 -0
- package/types/creative/PostProcessingPipeline.d.ts +109 -0
- package/types/creative/TransitionAnimator.d.ts +71 -0
- package/types/creative/index.d.ts +35 -0
- package/types/integrations/FigmaPlugin.d.ts +46 -0
- package/types/integrations/OBSMode.d.ts +74 -0
- package/types/integrations/ThreeJsPackage.d.ts +62 -0
- package/types/integrations/TouchDesignerExport.d.ts +36 -0
- package/types/integrations/Vib3React.d.ts +74 -0
- package/types/integrations/Vib3Svelte.d.ts +63 -0
- package/types/integrations/Vib3Vue.d.ts +55 -0
- package/types/integrations/index.d.ts +52 -0
- package/types/reactivity/SpatialInputSystem.d.ts +173 -0
- package/types/reactivity/index.d.ts +394 -0
- package/types/render/CommandBuffer.d.ts +169 -0
- package/types/render/RenderCommand.d.ts +312 -0
- package/types/render/RenderState.d.ts +279 -0
- package/types/render/RenderTarget.d.ts +254 -0
- package/types/render/ShaderProgram.d.ts +277 -0
- package/types/render/UnifiedRenderBridge.d.ts +143 -0
- package/types/render/WebGLBackend.d.ts +168 -0
- package/types/render/WebGPUBackend.d.ts +186 -0
- package/types/render/index.d.ts +141 -0
|
@@ -0,0 +1,735 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VIB3+ WebGPU Renderer
|
|
3
|
+
* Implements RendererContract for WebGPU-based 4D visualization
|
|
4
|
+
*
|
|
5
|
+
* @fileoverview WebGPU implementation for the VIB3+ SDK
|
|
6
|
+
* Supports 24 geometries with 6D rotation using compute shaders
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { WEBGPU_FEATURE_FLAGS, isWebGPUEnabled } from './index.ts';
|
|
10
|
+
import { TripleBufferedUniform, GPUDeviceLike, GPUQueueLike, GPUBufferLike } from './TripleBufferedUniform.ts';
|
|
11
|
+
import { PolytopeInstanceBuffer } from './PolytopeInstanceBuffer.ts';
|
|
12
|
+
import { GlassUniformLayout, createFloat32ArrayForLayout, writeField } from './BufferLayout.ts';
|
|
13
|
+
|
|
14
|
+
// WebGPU types (subset for compatibility)
|
|
15
|
+
interface GPUCanvasContext {
|
|
16
|
+
configure(config: GPUCanvasConfiguration): void;
|
|
17
|
+
getCurrentTexture(): GPUTexture;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface GPUCanvasConfiguration {
|
|
21
|
+
device: GPUDeviceLike;
|
|
22
|
+
format: string;
|
|
23
|
+
alphaMode?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface GPUTexture {
|
|
27
|
+
createView(): GPUTextureView;
|
|
28
|
+
destroy?(): void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface GPUTextureView {}
|
|
32
|
+
|
|
33
|
+
interface GPURenderPassDescriptor {
|
|
34
|
+
colorAttachments: GPURenderPassColorAttachment[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface GPURenderPassColorAttachment {
|
|
38
|
+
view: GPUTextureView;
|
|
39
|
+
clearValue?: { r: number; g: number; b: number; a: number };
|
|
40
|
+
loadOp: 'clear' | 'load';
|
|
41
|
+
storeOp: 'store' | 'discard';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface GPUAdapter {
|
|
45
|
+
requestDevice(): Promise<GPUDeviceLike>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface GPUShaderModule {}
|
|
49
|
+
|
|
50
|
+
interface GPURenderPipeline {}
|
|
51
|
+
|
|
52
|
+
interface GPUBindGroup {}
|
|
53
|
+
|
|
54
|
+
interface GPUBindGroupLayout {}
|
|
55
|
+
|
|
56
|
+
interface GPUCommandEncoder {
|
|
57
|
+
beginRenderPass(descriptor: GPURenderPassDescriptor): GPURenderPassEncoder;
|
|
58
|
+
finish(): GPUCommandBuffer;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface GPURenderPassEncoder {
|
|
62
|
+
setPipeline(pipeline: GPURenderPipeline): void;
|
|
63
|
+
setBindGroup(index: number, bindGroup: GPUBindGroup): void;
|
|
64
|
+
draw(vertexCount: number, instanceCount?: number): void;
|
|
65
|
+
end(): void;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface GPUCommandBuffer {}
|
|
69
|
+
|
|
70
|
+
export interface WebGPURendererOptions {
|
|
71
|
+
canvas: HTMLCanvasElement;
|
|
72
|
+
maxInstances?: number;
|
|
73
|
+
preferredFormat?: string;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface WebGPUFrameState {
|
|
77
|
+
time?: number;
|
|
78
|
+
params?: {
|
|
79
|
+
geometry?: number;
|
|
80
|
+
rot4dXY?: number;
|
|
81
|
+
rot4dXZ?: number;
|
|
82
|
+
rot4dYZ?: number;
|
|
83
|
+
rot4dXW?: number;
|
|
84
|
+
rot4dYW?: number;
|
|
85
|
+
rot4dZW?: number;
|
|
86
|
+
hue?: number;
|
|
87
|
+
intensity?: number;
|
|
88
|
+
saturation?: number;
|
|
89
|
+
gridDensity?: number;
|
|
90
|
+
morphFactor?: number;
|
|
91
|
+
chaos?: number;
|
|
92
|
+
speed?: number;
|
|
93
|
+
};
|
|
94
|
+
audio?: {
|
|
95
|
+
bass?: number;
|
|
96
|
+
mid?: number;
|
|
97
|
+
high?: number;
|
|
98
|
+
energy?: number;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* WebGPU Renderer implementing RendererContract
|
|
104
|
+
*/
|
|
105
|
+
export class WebGPURenderer {
|
|
106
|
+
private canvas: HTMLCanvasElement | null = null;
|
|
107
|
+
private device: GPUDeviceLike | null = null;
|
|
108
|
+
private context: GPUCanvasContext | null = null;
|
|
109
|
+
private format: string = 'bgra8unorm';
|
|
110
|
+
|
|
111
|
+
private pipeline: GPURenderPipeline | null = null;
|
|
112
|
+
private bindGroup: GPUBindGroup | null = null;
|
|
113
|
+
private uniformBuffer: TripleBufferedUniform | null = null;
|
|
114
|
+
private instanceBuffer: PolytopeInstanceBuffer | null = null;
|
|
115
|
+
|
|
116
|
+
private _initialized = false;
|
|
117
|
+
private _active = false;
|
|
118
|
+
private _width = 0;
|
|
119
|
+
private _height = 0;
|
|
120
|
+
private _pixelRatio = 1;
|
|
121
|
+
|
|
122
|
+
private time = 0;
|
|
123
|
+
private params: WebGPUFrameState['params'] = {};
|
|
124
|
+
|
|
125
|
+
readonly maxInstances: number;
|
|
126
|
+
|
|
127
|
+
constructor(options?: { maxInstances?: number }) {
|
|
128
|
+
this.maxInstances = options?.maxInstances ?? 1024;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Check if WebGPU is available and enabled
|
|
133
|
+
*/
|
|
134
|
+
static async isAvailable(): Promise<boolean> {
|
|
135
|
+
if (!isWebGPUEnabled()) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
if (typeof navigator === 'undefined' || !navigator.gpu) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
const adapter = await navigator.gpu.requestAdapter();
|
|
143
|
+
return adapter !== null;
|
|
144
|
+
} catch {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Enable WebGPU feature flag
|
|
151
|
+
*/
|
|
152
|
+
static enable(): void {
|
|
153
|
+
WEBGPU_FEATURE_FLAGS.enabled = true;
|
|
154
|
+
WEBGPU_FEATURE_FLAGS.reason = 'Enabled by application';
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Disable WebGPU feature flag
|
|
159
|
+
*/
|
|
160
|
+
static disable(): void {
|
|
161
|
+
WEBGPU_FEATURE_FLAGS.enabled = false;
|
|
162
|
+
WEBGPU_FEATURE_FLAGS.reason = 'Disabled by application';
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// ============================================
|
|
166
|
+
// RendererContract Implementation
|
|
167
|
+
// ============================================
|
|
168
|
+
|
|
169
|
+
get initialized(): boolean {
|
|
170
|
+
return this._initialized;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
get isActive(): boolean {
|
|
174
|
+
return this._active;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Initialize the WebGPU renderer
|
|
179
|
+
* @param context - { canvas: HTMLCanvasElement }
|
|
180
|
+
*/
|
|
181
|
+
async init(context: { canvas?: HTMLCanvasElement; canvasId?: string }): Promise<boolean> {
|
|
182
|
+
if (!isWebGPUEnabled()) {
|
|
183
|
+
console.warn('WebGPU is not enabled. Call WebGPURenderer.enable() first.');
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Get canvas
|
|
188
|
+
this.canvas = context.canvas ||
|
|
189
|
+
(context.canvasId ? document.getElementById(context.canvasId) as HTMLCanvasElement : null);
|
|
190
|
+
|
|
191
|
+
if (!this.canvas) {
|
|
192
|
+
console.error('WebGPURenderer: No canvas provided');
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Check WebGPU availability
|
|
197
|
+
if (typeof navigator === 'undefined' || !navigator.gpu) {
|
|
198
|
+
console.error('WebGPURenderer: WebGPU not supported in this browser');
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
// Request adapter and device
|
|
204
|
+
const adapter = await navigator.gpu.requestAdapter() as GPUAdapter | null;
|
|
205
|
+
if (!adapter) {
|
|
206
|
+
console.error('WebGPURenderer: Failed to get GPU adapter');
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
this.device = await adapter.requestDevice() as unknown as GPUDeviceLike;
|
|
211
|
+
if (!this.device) {
|
|
212
|
+
console.error('WebGPURenderer: Failed to get GPU device');
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Get canvas context
|
|
217
|
+
this.context = this.canvas.getContext('webgpu') as unknown as GPUCanvasContext;
|
|
218
|
+
if (!this.context) {
|
|
219
|
+
console.error('WebGPURenderer: Failed to get WebGPU context');
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Get preferred format
|
|
224
|
+
this.format = navigator.gpu.getPreferredCanvasFormat?.() || 'bgra8unorm';
|
|
225
|
+
|
|
226
|
+
// Configure context
|
|
227
|
+
this.context.configure({
|
|
228
|
+
device: this.device,
|
|
229
|
+
format: this.format,
|
|
230
|
+
alphaMode: 'premultiplied'
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Create buffers
|
|
234
|
+
await this.createBuffers();
|
|
235
|
+
|
|
236
|
+
// Create pipeline
|
|
237
|
+
await this.createPipeline();
|
|
238
|
+
|
|
239
|
+
this._initialized = true;
|
|
240
|
+
console.log('✅ WebGPU Renderer initialized');
|
|
241
|
+
return true;
|
|
242
|
+
|
|
243
|
+
} catch (error) {
|
|
244
|
+
console.error('WebGPURenderer: Initialization failed', error);
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Handle canvas resize
|
|
251
|
+
*/
|
|
252
|
+
resize(width: number, height: number, pixelRatio = 1): void {
|
|
253
|
+
this._width = width;
|
|
254
|
+
this._height = height;
|
|
255
|
+
this._pixelRatio = pixelRatio;
|
|
256
|
+
|
|
257
|
+
if (this.canvas) {
|
|
258
|
+
this.canvas.width = width * pixelRatio;
|
|
259
|
+
this.canvas.height = height * pixelRatio;
|
|
260
|
+
this.canvas.style.width = `${width}px`;
|
|
261
|
+
this.canvas.style.height = `${height}px`;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
console.log(`🎮 WebGPU resized to ${width}x${height} @${pixelRatio}x`);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Render a single frame
|
|
269
|
+
*/
|
|
270
|
+
render(frameState: WebGPUFrameState = {}): void {
|
|
271
|
+
if (!this._initialized || !this._active) return;
|
|
272
|
+
if (!this.device || !this.context || !this.pipeline) return;
|
|
273
|
+
|
|
274
|
+
// Update time
|
|
275
|
+
if (typeof frameState.time === 'number') {
|
|
276
|
+
this.time = frameState.time;
|
|
277
|
+
} else {
|
|
278
|
+
this.time += 0.016; // ~60fps default
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Update params
|
|
282
|
+
if (frameState.params) {
|
|
283
|
+
Object.assign(this.params, frameState.params);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Update uniform buffer
|
|
287
|
+
this.updateUniforms(frameState);
|
|
288
|
+
|
|
289
|
+
// Get current texture
|
|
290
|
+
const textureView = this.context.getCurrentTexture().createView();
|
|
291
|
+
|
|
292
|
+
// Create command encoder
|
|
293
|
+
const commandEncoder = (this.device as any).createCommandEncoder() as GPUCommandEncoder;
|
|
294
|
+
|
|
295
|
+
// Begin render pass
|
|
296
|
+
const renderPass = commandEncoder.beginRenderPass({
|
|
297
|
+
colorAttachments: [{
|
|
298
|
+
view: textureView,
|
|
299
|
+
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
|
300
|
+
loadOp: 'clear',
|
|
301
|
+
storeOp: 'store'
|
|
302
|
+
}]
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
// Draw
|
|
306
|
+
renderPass.setPipeline(this.pipeline);
|
|
307
|
+
if (this.bindGroup) {
|
|
308
|
+
renderPass.setBindGroup(0, this.bindGroup);
|
|
309
|
+
}
|
|
310
|
+
renderPass.draw(6); // Fullscreen quad
|
|
311
|
+
renderPass.end();
|
|
312
|
+
|
|
313
|
+
// Submit
|
|
314
|
+
(this.device.queue as any).submit([commandEncoder.finish()]);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Set active state
|
|
319
|
+
*/
|
|
320
|
+
setActive(active: boolean): void {
|
|
321
|
+
this._active = active;
|
|
322
|
+
console.log(`🎮 WebGPU Renderer ${active ? 'activated' : 'deactivated'}`);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Clean up all resources
|
|
327
|
+
*/
|
|
328
|
+
dispose(): void {
|
|
329
|
+
this._active = false;
|
|
330
|
+
this._initialized = false;
|
|
331
|
+
|
|
332
|
+
if (this.uniformBuffer) {
|
|
333
|
+
this.uniformBuffer.destroy();
|
|
334
|
+
this.uniformBuffer = null;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (this.instanceBuffer?.buffer && (this.instanceBuffer.buffer as any).destroy) {
|
|
338
|
+
(this.instanceBuffer.buffer as any).destroy();
|
|
339
|
+
}
|
|
340
|
+
this.instanceBuffer = null;
|
|
341
|
+
|
|
342
|
+
this.pipeline = null;
|
|
343
|
+
this.bindGroup = null;
|
|
344
|
+
this.device = null;
|
|
345
|
+
this.context = null;
|
|
346
|
+
this.canvas = null;
|
|
347
|
+
|
|
348
|
+
console.log('🧹 WebGPU Renderer disposed');
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// ============================================
|
|
352
|
+
// Private Methods
|
|
353
|
+
// ============================================
|
|
354
|
+
|
|
355
|
+
private async createBuffers(): Promise<void> {
|
|
356
|
+
if (!this.device) return;
|
|
357
|
+
|
|
358
|
+
// Create uniform buffer for frame data
|
|
359
|
+
this.uniformBuffer = new TripleBufferedUniform({
|
|
360
|
+
device: this.device,
|
|
361
|
+
byteSize: GlassUniformLayout.byteSize,
|
|
362
|
+
label: 'VIB3-Uniforms'
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
// Create instance buffer for polytope data
|
|
366
|
+
this.instanceBuffer = new PolytopeInstanceBuffer({
|
|
367
|
+
device: this.device,
|
|
368
|
+
maxInstances: this.maxInstances,
|
|
369
|
+
label: 'VIB3-Instances'
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
private async createPipeline(): Promise<void> {
|
|
374
|
+
if (!this.device) return;
|
|
375
|
+
|
|
376
|
+
// Create shader module
|
|
377
|
+
const shaderCode = this.getShaderCode();
|
|
378
|
+
const shaderModule = (this.device as any).createShaderModule({
|
|
379
|
+
code: shaderCode,
|
|
380
|
+
label: 'VIB3-Shader'
|
|
381
|
+
}) as GPUShaderModule;
|
|
382
|
+
|
|
383
|
+
// Create bind group layout
|
|
384
|
+
const bindGroupLayout = (this.device as any).createBindGroupLayout({
|
|
385
|
+
entries: [
|
|
386
|
+
{
|
|
387
|
+
binding: 0,
|
|
388
|
+
visibility: 0x1 | 0x2, // VERTEX | FRAGMENT
|
|
389
|
+
buffer: { type: 'uniform' }
|
|
390
|
+
}
|
|
391
|
+
],
|
|
392
|
+
label: 'VIB3-BindGroupLayout'
|
|
393
|
+
}) as GPUBindGroupLayout;
|
|
394
|
+
|
|
395
|
+
// Create pipeline layout
|
|
396
|
+
const pipelineLayout = (this.device as any).createPipelineLayout({
|
|
397
|
+
bindGroupLayouts: [bindGroupLayout],
|
|
398
|
+
label: 'VIB3-PipelineLayout'
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
// Create render pipeline
|
|
402
|
+
this.pipeline = (this.device as any).createRenderPipeline({
|
|
403
|
+
layout: pipelineLayout,
|
|
404
|
+
vertex: {
|
|
405
|
+
module: shaderModule,
|
|
406
|
+
entryPoint: 'vertexMain'
|
|
407
|
+
},
|
|
408
|
+
fragment: {
|
|
409
|
+
module: shaderModule,
|
|
410
|
+
entryPoint: 'fragmentMain',
|
|
411
|
+
targets: [{ format: this.format }]
|
|
412
|
+
},
|
|
413
|
+
primitive: {
|
|
414
|
+
topology: 'triangle-list'
|
|
415
|
+
},
|
|
416
|
+
label: 'VIB3-Pipeline'
|
|
417
|
+
}) as GPURenderPipeline;
|
|
418
|
+
|
|
419
|
+
// Create bind group
|
|
420
|
+
if (this.uniformBuffer) {
|
|
421
|
+
this.bindGroup = (this.device as any).createBindGroup({
|
|
422
|
+
layout: bindGroupLayout,
|
|
423
|
+
entries: [this.uniformBuffer.bindGroupEntry(0)],
|
|
424
|
+
label: 'VIB3-BindGroup'
|
|
425
|
+
}) as GPUBindGroup;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
private updateUniforms(frameState: WebGPUFrameState): void {
|
|
430
|
+
if (!this.uniformBuffer) return;
|
|
431
|
+
|
|
432
|
+
const data = this.uniformBuffer.data;
|
|
433
|
+
|
|
434
|
+
// Write time and resolution to metrics slot
|
|
435
|
+
const metrics = new Float32Array([
|
|
436
|
+
this.time,
|
|
437
|
+
this._width * this._pixelRatio,
|
|
438
|
+
this._height * this._pixelRatio,
|
|
439
|
+
this._pixelRatio
|
|
440
|
+
]);
|
|
441
|
+
writeField(GlassUniformLayout, data, 'metrics', metrics);
|
|
442
|
+
|
|
443
|
+
// Write rotation to euler slot
|
|
444
|
+
const euler = new Float32Array([
|
|
445
|
+
this.params.rot4dXY ?? 0,
|
|
446
|
+
this.params.rot4dXZ ?? 0,
|
|
447
|
+
this.params.rot4dYZ ?? 0,
|
|
448
|
+
0
|
|
449
|
+
]);
|
|
450
|
+
writeField(GlassUniformLayout, data, 'euler', euler);
|
|
451
|
+
|
|
452
|
+
// Write 4D rotation to rotor4d slot
|
|
453
|
+
const rotor = new Float32Array([
|
|
454
|
+
this.params.rot4dXW ?? 0,
|
|
455
|
+
this.params.rot4dYW ?? 0,
|
|
456
|
+
this.params.rot4dZW ?? 0,
|
|
457
|
+
this.params.geometry ?? 0
|
|
458
|
+
]);
|
|
459
|
+
writeField(GlassUniformLayout, data, 'rotor4d', rotor);
|
|
460
|
+
|
|
461
|
+
// Write visual parameters
|
|
462
|
+
const visual = new Float32Array([
|
|
463
|
+
(this.params.hue ?? 200) / 360,
|
|
464
|
+
this.params.intensity ?? 0.7,
|
|
465
|
+
this.params.saturation ?? 0.8,
|
|
466
|
+
this.params.morphFactor ?? 1.0
|
|
467
|
+
]);
|
|
468
|
+
writeField(GlassUniformLayout, data, 'visual', visual);
|
|
469
|
+
|
|
470
|
+
// Write audio data
|
|
471
|
+
const audio = new Float32Array([
|
|
472
|
+
frameState.audio?.bass ?? 0,
|
|
473
|
+
frameState.audio?.mid ?? 0,
|
|
474
|
+
frameState.audio?.high ?? 0,
|
|
475
|
+
frameState.audio?.energy ?? 0
|
|
476
|
+
]);
|
|
477
|
+
writeField(GlassUniformLayout, data, 'audio', audio);
|
|
478
|
+
|
|
479
|
+
// Upload to GPU
|
|
480
|
+
this.uniformBuffer.upload();
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
private getShaderCode(): string {
|
|
484
|
+
return VIB3_WGSL_SHADER;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* WGSL shader for VIB3+ 4D visualization
|
|
490
|
+
*/
|
|
491
|
+
const VIB3_WGSL_SHADER = `
|
|
492
|
+
// VIB3+ 4D Visualization Shader (WGSL)
|
|
493
|
+
// Supports 24 geometries with 6D rotation
|
|
494
|
+
|
|
495
|
+
struct Uniforms {
|
|
496
|
+
leftViewProj: mat4x4<f32>,
|
|
497
|
+
rightViewProj: mat4x4<f32>,
|
|
498
|
+
headMatrix: mat4x4<f32>,
|
|
499
|
+
rotor4d: vec4<f32>, // XW, YW, ZW rotations + geometry
|
|
500
|
+
euler: vec4<f32>, // XY, XZ, YZ rotations
|
|
501
|
+
metrics: vec4<f32>, // time, width, height, pixelRatio
|
|
502
|
+
audio: vec4<f32>, // bass, mid, high, energy
|
|
503
|
+
localization: vec4<f32>,
|
|
504
|
+
visual: vec4<f32>, // hue, intensity, saturation, morphFactor
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
|
|
508
|
+
|
|
509
|
+
struct VertexOutput {
|
|
510
|
+
@builtin(position) position: vec4<f32>,
|
|
511
|
+
@location(0) uv: vec2<f32>,
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Fullscreen triangle vertices
|
|
515
|
+
const VERTICES = array<vec2<f32>, 6>(
|
|
516
|
+
vec2<f32>(-1.0, -1.0),
|
|
517
|
+
vec2<f32>( 1.0, -1.0),
|
|
518
|
+
vec2<f32>(-1.0, 1.0),
|
|
519
|
+
vec2<f32>(-1.0, 1.0),
|
|
520
|
+
vec2<f32>( 1.0, -1.0),
|
|
521
|
+
vec2<f32>( 1.0, 1.0)
|
|
522
|
+
);
|
|
523
|
+
|
|
524
|
+
@vertex
|
|
525
|
+
fn vertexMain(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
|
|
526
|
+
var output: VertexOutput;
|
|
527
|
+
let pos = VERTICES[vertexIndex];
|
|
528
|
+
output.position = vec4<f32>(pos, 0.0, 1.0);
|
|
529
|
+
output.uv = pos * 0.5 + 0.5;
|
|
530
|
+
return output;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// 4D rotation matrices
|
|
534
|
+
fn rotateXY(angle: f32) -> mat4x4<f32> {
|
|
535
|
+
let c = cos(angle);
|
|
536
|
+
let s = sin(angle);
|
|
537
|
+
return mat4x4<f32>(
|
|
538
|
+
vec4<f32>(c, -s, 0.0, 0.0),
|
|
539
|
+
vec4<f32>(s, c, 0.0, 0.0),
|
|
540
|
+
vec4<f32>(0.0, 0.0, 1.0, 0.0),
|
|
541
|
+
vec4<f32>(0.0, 0.0, 0.0, 1.0)
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
fn rotateXZ(angle: f32) -> mat4x4<f32> {
|
|
546
|
+
let c = cos(angle);
|
|
547
|
+
let s = sin(angle);
|
|
548
|
+
return mat4x4<f32>(
|
|
549
|
+
vec4<f32>(c, 0.0, -s, 0.0),
|
|
550
|
+
vec4<f32>(0.0, 1.0, 0.0, 0.0),
|
|
551
|
+
vec4<f32>(s, 0.0, c, 0.0),
|
|
552
|
+
vec4<f32>(0.0, 0.0, 0.0, 1.0)
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
fn rotateYZ(angle: f32) -> mat4x4<f32> {
|
|
557
|
+
let c = cos(angle);
|
|
558
|
+
let s = sin(angle);
|
|
559
|
+
return mat4x4<f32>(
|
|
560
|
+
vec4<f32>(1.0, 0.0, 0.0, 0.0),
|
|
561
|
+
vec4<f32>(0.0, c, -s, 0.0),
|
|
562
|
+
vec4<f32>(0.0, s, c, 0.0),
|
|
563
|
+
vec4<f32>(0.0, 0.0, 0.0, 1.0)
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
fn rotateXW(angle: f32) -> mat4x4<f32> {
|
|
568
|
+
let c = cos(angle);
|
|
569
|
+
let s = sin(angle);
|
|
570
|
+
return mat4x4<f32>(
|
|
571
|
+
vec4<f32>(c, 0.0, 0.0, -s),
|
|
572
|
+
vec4<f32>(0.0, 1.0, 0.0, 0.0),
|
|
573
|
+
vec4<f32>(0.0, 0.0, 1.0, 0.0),
|
|
574
|
+
vec4<f32>(s, 0.0, 0.0, c)
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
fn rotateYW(angle: f32) -> mat4x4<f32> {
|
|
579
|
+
let c = cos(angle);
|
|
580
|
+
let s = sin(angle);
|
|
581
|
+
return mat4x4<f32>(
|
|
582
|
+
vec4<f32>(1.0, 0.0, 0.0, 0.0),
|
|
583
|
+
vec4<f32>(0.0, c, 0.0, -s),
|
|
584
|
+
vec4<f32>(0.0, 0.0, 1.0, 0.0),
|
|
585
|
+
vec4<f32>(0.0, s, 0.0, c)
|
|
586
|
+
);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
fn rotateZW(angle: f32) -> mat4x4<f32> {
|
|
590
|
+
let c = cos(angle);
|
|
591
|
+
let s = sin(angle);
|
|
592
|
+
return mat4x4<f32>(
|
|
593
|
+
vec4<f32>(1.0, 0.0, 0.0, 0.0),
|
|
594
|
+
vec4<f32>(0.0, 1.0, 0.0, 0.0),
|
|
595
|
+
vec4<f32>(0.0, 0.0, c, -s),
|
|
596
|
+
vec4<f32>(0.0, 0.0, s, c)
|
|
597
|
+
);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// Apply all 6D rotations
|
|
601
|
+
fn apply6DRotation(pos: vec4<f32>, time: f32) -> vec4<f32> {
|
|
602
|
+
var p = pos;
|
|
603
|
+
p = rotateXY(uniforms.euler.x + time * 0.05) * p;
|
|
604
|
+
p = rotateXZ(uniforms.euler.y + time * 0.06) * p;
|
|
605
|
+
p = rotateYZ(uniforms.euler.z + time * 0.04) * p;
|
|
606
|
+
p = rotateXW(uniforms.rotor4d.x + time * 0.07) * p;
|
|
607
|
+
p = rotateYW(uniforms.rotor4d.y + time * 0.08) * p;
|
|
608
|
+
p = rotateZW(uniforms.rotor4d.z + time * 0.09) * p;
|
|
609
|
+
return p;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// Base geometry SDFs (0-7)
|
|
613
|
+
fn baseGeometry(p: vec4<f32>, geometryType: f32) -> f32 {
|
|
614
|
+
let gType = floor(geometryType);
|
|
615
|
+
|
|
616
|
+
if (gType < 0.5) {
|
|
617
|
+
// Tetrahedron
|
|
618
|
+
return max(max(max(abs(p.x + p.y) - p.z, abs(p.x - p.y) - p.z),
|
|
619
|
+
abs(p.x + p.y) + p.z), abs(p.x - p.y) + p.z) / sqrt(3.0);
|
|
620
|
+
} else if (gType < 1.5) {
|
|
621
|
+
// Hypercube
|
|
622
|
+
let q = abs(p) - vec4<f32>(0.8);
|
|
623
|
+
return length(max(q, vec4<f32>(0.0))) + min(max(max(max(q.x, q.y), q.z), q.w), 0.0);
|
|
624
|
+
} else if (gType < 2.5) {
|
|
625
|
+
// Sphere
|
|
626
|
+
return length(p) - 1.0;
|
|
627
|
+
} else if (gType < 3.5) {
|
|
628
|
+
// Torus
|
|
629
|
+
let t = vec2<f32>(length(p.xy) - 0.8, p.z);
|
|
630
|
+
return length(t) - 0.3;
|
|
631
|
+
} else if (gType < 4.5) {
|
|
632
|
+
// Klein Bottle (simplified)
|
|
633
|
+
let r = length(p.xy);
|
|
634
|
+
return abs(r - 0.7) - 0.2 + sin(atan2(p.y, p.x) * 3.0 + p.z * 5.0) * 0.1;
|
|
635
|
+
} else if (gType < 5.5) {
|
|
636
|
+
// Fractal
|
|
637
|
+
return length(p) - 0.8 + sin(p.x * 5.0) * sin(p.y * 5.0) * sin(p.z * 5.0) * 0.2;
|
|
638
|
+
} else if (gType < 6.5) {
|
|
639
|
+
// Wave
|
|
640
|
+
let time = uniforms.metrics.x;
|
|
641
|
+
return abs(p.z - sin(p.x * 5.0 + time) * cos(p.y * 5.0 + time) * 0.3) - 0.1;
|
|
642
|
+
} else {
|
|
643
|
+
// Crystal
|
|
644
|
+
let q = abs(p);
|
|
645
|
+
return max(max(max(q.x, q.y), q.z), q.w) - 0.8;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// Hypersphere core wrapper (8-15)
|
|
650
|
+
fn hypersphereCore(p: vec4<f32>, baseType: f32) -> f32 {
|
|
651
|
+
let baseShape = baseGeometry(p, baseType);
|
|
652
|
+
let sphereField = length(p) - 1.2;
|
|
653
|
+
return max(baseShape, sphereField);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// Hypertetrahedron core wrapper (16-23)
|
|
657
|
+
fn hypertetrahedronCore(p: vec4<f32>, baseType: f32) -> f32 {
|
|
658
|
+
let baseShape = baseGeometry(p, baseType);
|
|
659
|
+
let tetraField = max(max(max(
|
|
660
|
+
abs(p.x + p.y) - p.z - p.w,
|
|
661
|
+
abs(p.x - p.y) - p.z + p.w),
|
|
662
|
+
abs(p.x + p.y) + p.z - p.w),
|
|
663
|
+
abs(p.x - p.y) + p.z + p.w) / sqrt(4.0);
|
|
664
|
+
return max(baseShape, tetraField);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// Main geometry dispatcher (0-23)
|
|
668
|
+
fn geometry(p: vec4<f32>, geometryIndex: f32) -> f32 {
|
|
669
|
+
if (geometryIndex < 8.0) {
|
|
670
|
+
return baseGeometry(p, geometryIndex);
|
|
671
|
+
} else if (geometryIndex < 16.0) {
|
|
672
|
+
return hypersphereCore(p, geometryIndex - 8.0);
|
|
673
|
+
} else {
|
|
674
|
+
return hypertetrahedronCore(p, geometryIndex - 16.0);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
// HSV to RGB conversion
|
|
679
|
+
fn hsv2rgb(c: vec3<f32>) -> vec3<f32> {
|
|
680
|
+
let K = vec4<f32>(1.0, 2.0/3.0, 1.0/3.0, 3.0);
|
|
681
|
+
let p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
|
682
|
+
return c.z * mix(K.xxx, clamp(p - K.xxx, vec3<f32>(0.0), vec3<f32>(1.0)), c.y);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
@fragment
|
|
686
|
+
fn fragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
687
|
+
let time = uniforms.metrics.x;
|
|
688
|
+
let resolution = vec2<f32>(uniforms.metrics.y, uniforms.metrics.z);
|
|
689
|
+
|
|
690
|
+
// Normalized coordinates
|
|
691
|
+
let uv = (input.uv * 2.0 - 1.0) * vec2<f32>(resolution.x / resolution.y, 1.0);
|
|
692
|
+
|
|
693
|
+
// Grid density from visual params
|
|
694
|
+
let gridDensity = 15.0;
|
|
695
|
+
|
|
696
|
+
// Create 4D point
|
|
697
|
+
var pos = vec4<f32>(
|
|
698
|
+
uv / gridDensity,
|
|
699
|
+
sin(time * 0.3) * 0.5,
|
|
700
|
+
cos(time * 0.2) * 0.5
|
|
701
|
+
);
|
|
702
|
+
|
|
703
|
+
// Apply 6D rotation
|
|
704
|
+
pos = apply6DRotation(pos, time);
|
|
705
|
+
|
|
706
|
+
// Apply morph factor
|
|
707
|
+
let morphFactor = uniforms.visual.w;
|
|
708
|
+
pos = pos * morphFactor;
|
|
709
|
+
|
|
710
|
+
// Get geometry index
|
|
711
|
+
let geometryIndex = uniforms.rotor4d.w;
|
|
712
|
+
|
|
713
|
+
// Calculate distance
|
|
714
|
+
let dist = geometry(pos, geometryIndex);
|
|
715
|
+
|
|
716
|
+
// Faceted rendering
|
|
717
|
+
let edge = smoothstep(0.02, 0.0, abs(dist));
|
|
718
|
+
let fill = smoothstep(0.1, 0.0, dist) * 0.3;
|
|
719
|
+
|
|
720
|
+
// Color from visual params
|
|
721
|
+
let hue = uniforms.visual.x + dist * 0.2 + time * 0.05;
|
|
722
|
+
let saturation = uniforms.visual.z;
|
|
723
|
+
let intensity = uniforms.visual.y;
|
|
724
|
+
|
|
725
|
+
// Audio reactive intensity boost
|
|
726
|
+
let audioBoost = 1.0 + uniforms.audio.w * 0.3;
|
|
727
|
+
|
|
728
|
+
let color = hsv2rgb(vec3<f32>(hue, saturation, intensity * audioBoost));
|
|
729
|
+
let alpha = (edge + fill) * intensity;
|
|
730
|
+
|
|
731
|
+
return vec4<f32>(color * alpha, alpha);
|
|
732
|
+
}
|
|
733
|
+
`;
|
|
734
|
+
|
|
735
|
+
export default WebGPURenderer;
|