@vib3code/sdk 2.0.3-canary.60bc0f0 → 2.0.3-canary.74aebb4
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/DOCS/EXPANSION_DESIGN.md +977 -0
- package/DOCS/EXPANSION_DESIGN_ULTRA.md +387 -0
- package/DOCS/MASTER_PLAN_2026-01-31.md +2 -2
- package/DOCS/OPTIMIZATION_PLAN_MATH.md +118 -0
- package/DOCS/SYSTEM_INVENTORY.md +2 -2
- package/DOCS/WEBGPU_STATUS.md +119 -38
- package/DOCS/archive/WEBGPU_STATUS_2026-02-15_STALE.md +38 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-16.md +108 -0
- package/DOCS/dev-tracks/PERF_UPGRADE_2026-02-16.md +308 -0
- package/docs/webgpu-live.html +1 -1
- package/package.json +1 -1
- package/src/agent/mcp/MCPServer.js +195 -136
- package/src/agent/mcp/tools.js +45 -32
- package/src/experimental/GameLoop.js +72 -0
- package/src/experimental/LatticePhysics.js +100 -0
- package/src/experimental/LiveDirector.js +143 -0
- package/src/experimental/PlayerController4D.js +154 -0
- package/src/experimental/VIB3Actor.js +138 -0
- package/src/experimental/VIB3Compositor.js +117 -0
- package/src/experimental/VIB3Link.js +122 -0
- package/src/experimental/VIB3Orchestrator.js +146 -0
- package/src/experimental/VIB3Universe.js +109 -0
- package/src/experimental/demos/CrystalLabyrinth.js +202 -0
- package/src/faceted/FacetedSystem.js +19 -6
- package/src/geometry/generators/Crystal.js +2 -2
- package/src/holograms/HolographicVisualizer.js +58 -89
- package/src/math/Mat4x4.js +122 -6
- package/src/math/Rotor4D.js +93 -39
- package/src/math/Vec4.js +119 -78
- package/src/quantum/QuantumVisualizer.js +24 -20
- package/src/render/ShaderLoader.js +38 -0
- package/src/render/ShaderProgram.js +4 -4
- package/src/render/UnifiedRenderBridge.js +1 -1
- package/src/render/backends/WebGPUBackend.js +8 -4
- package/src/shaders/common/geometry24.glsl +65 -0
- package/src/shaders/common/geometry24.wgsl +54 -0
- package/src/shaders/common/rotation4d.glsl +4 -4
- package/src/shaders/common/rotation4d.wgsl +2 -2
- package/src/shaders/common/uniforms.wgsl +15 -8
- package/src/shaders/faceted/faceted.frag.wgsl +19 -6
- package/src/shaders/holographic/holographic.frag.wgsl +7 -5
- package/src/shaders/quantum/quantum.frag.wgsl +7 -5
- package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +2 -2
- package/tools/shader-sync-verify.js +6 -4
package/src/math/Vec4.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Vec4 - 4D Vector Class
|
|
3
3
|
*
|
|
4
4
|
* Represents a point or direction in 4-dimensional space.
|
|
5
|
-
* Uses
|
|
5
|
+
* Uses plain numeric properties internally for minimal allocation overhead.
|
|
6
|
+
* GPU-compatible Float32Array created on demand via toFloat32Array().
|
|
6
7
|
*
|
|
7
8
|
* @example
|
|
8
9
|
* const v = new Vec4(1, 2, 3, 0.5);
|
|
@@ -19,26 +20,66 @@ export class Vec4 {
|
|
|
19
20
|
* @param {number} w - W component (4th dimension)
|
|
20
21
|
*/
|
|
21
22
|
constructor(x = 0, y = 0, z = 0, w = 0) {
|
|
22
|
-
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
25
|
-
this.
|
|
26
|
-
this.data[2] = z;
|
|
27
|
-
this.data[3] = w;
|
|
23
|
+
this._x = x;
|
|
24
|
+
this._y = y;
|
|
25
|
+
this._z = z;
|
|
26
|
+
this._w = w;
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
// Property accessors
|
|
31
|
-
get x() { return this.
|
|
32
|
-
set x(v) { this.
|
|
29
|
+
// Property accessors
|
|
30
|
+
get x() { return this._x; }
|
|
31
|
+
set x(v) { this._x = v; }
|
|
33
32
|
|
|
34
|
-
get y() { return this.
|
|
35
|
-
set y(v) { this.
|
|
33
|
+
get y() { return this._y; }
|
|
34
|
+
set y(v) { this._y = v; }
|
|
36
35
|
|
|
37
|
-
get z() { return this.
|
|
38
|
-
set z(v) { this.
|
|
36
|
+
get z() { return this._z; }
|
|
37
|
+
set z(v) { this._z = v; }
|
|
39
38
|
|
|
40
|
-
get w() { return this.
|
|
41
|
-
set w(v) { this.
|
|
39
|
+
get w() { return this._w; }
|
|
40
|
+
set w(v) { this._w = v; }
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Backward-compatible .data getter.
|
|
44
|
+
* Returns a Float32Array snapshot of current values.
|
|
45
|
+
* Note: writes to the returned array do NOT propagate back.
|
|
46
|
+
* Use setComponent(index, value) for index-based mutation.
|
|
47
|
+
* @returns {Float32Array}
|
|
48
|
+
*/
|
|
49
|
+
get data() {
|
|
50
|
+
return new Float32Array([this._x, this._y, this._z, this._w]);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Set a component by index (0=x, 1=y, 2=z, 3=w)
|
|
55
|
+
* @param {number} index - Component index (0-3)
|
|
56
|
+
* @param {number} value - New value
|
|
57
|
+
* @returns {Vec4} this
|
|
58
|
+
*/
|
|
59
|
+
setComponent(index, value) {
|
|
60
|
+
switch (index) {
|
|
61
|
+
case 0: this._x = value; break;
|
|
62
|
+
case 1: this._y = value; break;
|
|
63
|
+
case 2: this._z = value; break;
|
|
64
|
+
case 3: this._w = value; break;
|
|
65
|
+
}
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get a component by index (0=x, 1=y, 2=z, 3=w)
|
|
71
|
+
* @param {number} index - Component index (0-3)
|
|
72
|
+
* @returns {number}
|
|
73
|
+
*/
|
|
74
|
+
getComponent(index) {
|
|
75
|
+
switch (index) {
|
|
76
|
+
case 0: return this._x;
|
|
77
|
+
case 1: return this._y;
|
|
78
|
+
case 2: return this._z;
|
|
79
|
+
case 3: return this._w;
|
|
80
|
+
default: return 0;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
42
83
|
|
|
43
84
|
/**
|
|
44
85
|
* Create a Vec4 from an array
|
|
@@ -54,7 +95,7 @@ export class Vec4 {
|
|
|
54
95
|
* @returns {Vec4}
|
|
55
96
|
*/
|
|
56
97
|
clone() {
|
|
57
|
-
return new Vec4(this.
|
|
98
|
+
return new Vec4(this._x, this._y, this._z, this._w);
|
|
58
99
|
}
|
|
59
100
|
|
|
60
101
|
/**
|
|
@@ -63,10 +104,10 @@ export class Vec4 {
|
|
|
63
104
|
* @returns {Vec4} this (for chaining)
|
|
64
105
|
*/
|
|
65
106
|
copy(v) {
|
|
66
|
-
this.
|
|
67
|
-
this.
|
|
68
|
-
this.
|
|
69
|
-
this.
|
|
107
|
+
this._x = v._x;
|
|
108
|
+
this._y = v._y;
|
|
109
|
+
this._z = v._z;
|
|
110
|
+
this._w = v._w;
|
|
70
111
|
return this;
|
|
71
112
|
}
|
|
72
113
|
|
|
@@ -79,10 +120,10 @@ export class Vec4 {
|
|
|
79
120
|
* @returns {Vec4} this
|
|
80
121
|
*/
|
|
81
122
|
set(x, y, z, w) {
|
|
82
|
-
this.
|
|
83
|
-
this.
|
|
84
|
-
this.
|
|
85
|
-
this.
|
|
123
|
+
this._x = x;
|
|
124
|
+
this._y = y;
|
|
125
|
+
this._z = z;
|
|
126
|
+
this._w = w;
|
|
86
127
|
return this;
|
|
87
128
|
}
|
|
88
129
|
|
|
@@ -93,10 +134,10 @@ export class Vec4 {
|
|
|
93
134
|
*/
|
|
94
135
|
add(v) {
|
|
95
136
|
return new Vec4(
|
|
96
|
-
this.
|
|
97
|
-
this.
|
|
98
|
-
this.
|
|
99
|
-
this.
|
|
137
|
+
this._x + v._x,
|
|
138
|
+
this._y + v._y,
|
|
139
|
+
this._z + v._z,
|
|
140
|
+
this._w + v._w
|
|
100
141
|
);
|
|
101
142
|
}
|
|
102
143
|
|
|
@@ -106,10 +147,10 @@ export class Vec4 {
|
|
|
106
147
|
* @returns {Vec4} this
|
|
107
148
|
*/
|
|
108
149
|
addInPlace(v) {
|
|
109
|
-
this.
|
|
110
|
-
this.
|
|
111
|
-
this.
|
|
112
|
-
this.
|
|
150
|
+
this._x += v._x;
|
|
151
|
+
this._y += v._y;
|
|
152
|
+
this._z += v._z;
|
|
153
|
+
this._w += v._w;
|
|
113
154
|
return this;
|
|
114
155
|
}
|
|
115
156
|
|
|
@@ -120,10 +161,10 @@ export class Vec4 {
|
|
|
120
161
|
*/
|
|
121
162
|
sub(v) {
|
|
122
163
|
return new Vec4(
|
|
123
|
-
this.
|
|
124
|
-
this.
|
|
125
|
-
this.
|
|
126
|
-
this.
|
|
164
|
+
this._x - v._x,
|
|
165
|
+
this._y - v._y,
|
|
166
|
+
this._z - v._z,
|
|
167
|
+
this._w - v._w
|
|
127
168
|
);
|
|
128
169
|
}
|
|
129
170
|
|
|
@@ -133,10 +174,10 @@ export class Vec4 {
|
|
|
133
174
|
* @returns {Vec4} this
|
|
134
175
|
*/
|
|
135
176
|
subInPlace(v) {
|
|
136
|
-
this.
|
|
137
|
-
this.
|
|
138
|
-
this.
|
|
139
|
-
this.
|
|
177
|
+
this._x -= v._x;
|
|
178
|
+
this._y -= v._y;
|
|
179
|
+
this._z -= v._z;
|
|
180
|
+
this._w -= v._w;
|
|
140
181
|
return this;
|
|
141
182
|
}
|
|
142
183
|
|
|
@@ -147,10 +188,10 @@ export class Vec4 {
|
|
|
147
188
|
*/
|
|
148
189
|
scale(s) {
|
|
149
190
|
return new Vec4(
|
|
150
|
-
this.
|
|
151
|
-
this.
|
|
152
|
-
this.
|
|
153
|
-
this.
|
|
191
|
+
this._x * s,
|
|
192
|
+
this._y * s,
|
|
193
|
+
this._z * s,
|
|
194
|
+
this._w * s
|
|
154
195
|
);
|
|
155
196
|
}
|
|
156
197
|
|
|
@@ -160,10 +201,10 @@ export class Vec4 {
|
|
|
160
201
|
* @returns {Vec4} this
|
|
161
202
|
*/
|
|
162
203
|
scaleInPlace(s) {
|
|
163
|
-
this.
|
|
164
|
-
this.
|
|
165
|
-
this.
|
|
166
|
-
this.
|
|
204
|
+
this._x *= s;
|
|
205
|
+
this._y *= s;
|
|
206
|
+
this._z *= s;
|
|
207
|
+
this._w *= s;
|
|
167
208
|
return this;
|
|
168
209
|
}
|
|
169
210
|
|
|
@@ -174,10 +215,10 @@ export class Vec4 {
|
|
|
174
215
|
*/
|
|
175
216
|
multiply(v) {
|
|
176
217
|
return new Vec4(
|
|
177
|
-
this.
|
|
178
|
-
this.
|
|
179
|
-
this.
|
|
180
|
-
this.
|
|
218
|
+
this._x * v._x,
|
|
219
|
+
this._y * v._y,
|
|
220
|
+
this._z * v._z,
|
|
221
|
+
this._w * v._w
|
|
181
222
|
);
|
|
182
223
|
}
|
|
183
224
|
|
|
@@ -186,7 +227,7 @@ export class Vec4 {
|
|
|
186
227
|
* @returns {Vec4} New vector
|
|
187
228
|
*/
|
|
188
229
|
negate() {
|
|
189
|
-
return new Vec4(-this.
|
|
230
|
+
return new Vec4(-this._x, -this._y, -this._z, -this._w);
|
|
190
231
|
}
|
|
191
232
|
|
|
192
233
|
/**
|
|
@@ -194,10 +235,10 @@ export class Vec4 {
|
|
|
194
235
|
* @returns {Vec4} this
|
|
195
236
|
*/
|
|
196
237
|
negateInPlace() {
|
|
197
|
-
this.
|
|
198
|
-
this.
|
|
199
|
-
this.
|
|
200
|
-
this.
|
|
238
|
+
this._x = -this._x;
|
|
239
|
+
this._y = -this._y;
|
|
240
|
+
this._z = -this._z;
|
|
241
|
+
this._w = -this._w;
|
|
201
242
|
return this;
|
|
202
243
|
}
|
|
203
244
|
|
|
@@ -207,7 +248,7 @@ export class Vec4 {
|
|
|
207
248
|
* @returns {number}
|
|
208
249
|
*/
|
|
209
250
|
dot(v) {
|
|
210
|
-
return this.
|
|
251
|
+
return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
|
|
211
252
|
}
|
|
212
253
|
|
|
213
254
|
/**
|
|
@@ -215,7 +256,7 @@ export class Vec4 {
|
|
|
215
256
|
* @returns {number}
|
|
216
257
|
*/
|
|
217
258
|
lengthSquared() {
|
|
218
|
-
return this.
|
|
259
|
+
return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
|
|
219
260
|
}
|
|
220
261
|
|
|
221
262
|
/**
|
|
@@ -277,10 +318,10 @@ export class Vec4 {
|
|
|
277
318
|
*/
|
|
278
319
|
lerp(v, t) {
|
|
279
320
|
return new Vec4(
|
|
280
|
-
this.
|
|
281
|
-
this.
|
|
282
|
-
this.
|
|
283
|
-
this.
|
|
321
|
+
this._x + (v._x - this._x) * t,
|
|
322
|
+
this._y + (v._y - this._y) * t,
|
|
323
|
+
this._z + (v._z - this._z) * t,
|
|
324
|
+
this._w + (v._w - this._w) * t
|
|
284
325
|
);
|
|
285
326
|
}
|
|
286
327
|
|
|
@@ -292,10 +333,10 @@ export class Vec4 {
|
|
|
292
333
|
*/
|
|
293
334
|
equals(v, epsilon = 1e-6) {
|
|
294
335
|
return (
|
|
295
|
-
Math.abs(this.
|
|
296
|
-
Math.abs(this.
|
|
297
|
-
Math.abs(this.
|
|
298
|
-
Math.abs(this.
|
|
336
|
+
Math.abs(this._x - v._x) < epsilon &&
|
|
337
|
+
Math.abs(this._y - v._y) < epsilon &&
|
|
338
|
+
Math.abs(this._z - v._z) < epsilon &&
|
|
339
|
+
Math.abs(this._w - v._w) < epsilon
|
|
299
340
|
);
|
|
300
341
|
}
|
|
301
342
|
|
|
@@ -321,10 +362,10 @@ export class Vec4 {
|
|
|
321
362
|
d = options.distance ?? options.d ?? 2;
|
|
322
363
|
}
|
|
323
364
|
const epsilon = options.epsilon ?? 1e-5;
|
|
324
|
-
const denom = d - this.
|
|
365
|
+
const denom = d - this._w;
|
|
325
366
|
const clamped = Math.abs(denom) < epsilon ? (denom >= 0 ? epsilon : -epsilon) : denom;
|
|
326
367
|
const scale = 1 / clamped;
|
|
327
|
-
return new Vec4(this.
|
|
368
|
+
return new Vec4(this._x * scale, this._y * scale, this._z * scale, 0);
|
|
328
369
|
}
|
|
329
370
|
|
|
330
371
|
/**
|
|
@@ -335,10 +376,10 @@ export class Vec4 {
|
|
|
335
376
|
*/
|
|
336
377
|
projectStereographic(options = {}) {
|
|
337
378
|
const epsilon = options.epsilon ?? 1e-5;
|
|
338
|
-
const denom = 1 - this.
|
|
379
|
+
const denom = 1 - this._w;
|
|
339
380
|
const clamped = Math.abs(denom) < epsilon ? (denom >= 0 ? epsilon : -epsilon) : denom;
|
|
340
381
|
const scale = 1 / clamped;
|
|
341
|
-
return new Vec4(this.
|
|
382
|
+
return new Vec4(this._x * scale, this._y * scale, this._z * scale, 0);
|
|
342
383
|
}
|
|
343
384
|
|
|
344
385
|
/**
|
|
@@ -347,7 +388,7 @@ export class Vec4 {
|
|
|
347
388
|
* @returns {Vec4} Projected point (w component is 0)
|
|
348
389
|
*/
|
|
349
390
|
projectOrthographic() {
|
|
350
|
-
return new Vec4(this.
|
|
391
|
+
return new Vec4(this._x, this._y, this._z, 0);
|
|
351
392
|
}
|
|
352
393
|
|
|
353
394
|
/**
|
|
@@ -355,7 +396,7 @@ export class Vec4 {
|
|
|
355
396
|
* @returns {number[]}
|
|
356
397
|
*/
|
|
357
398
|
toArray() {
|
|
358
|
-
return [this.
|
|
399
|
+
return [this._x, this._y, this._z, this._w];
|
|
359
400
|
}
|
|
360
401
|
|
|
361
402
|
/**
|
|
@@ -363,7 +404,7 @@ export class Vec4 {
|
|
|
363
404
|
* @returns {Float32Array}
|
|
364
405
|
*/
|
|
365
406
|
toFloat32Array() {
|
|
366
|
-
return new Float32Array(this.
|
|
407
|
+
return new Float32Array([this._x, this._y, this._z, this._w]);
|
|
367
408
|
}
|
|
368
409
|
|
|
369
410
|
/**
|
|
@@ -371,7 +412,7 @@ export class Vec4 {
|
|
|
371
412
|
* @returns {number[]}
|
|
372
413
|
*/
|
|
373
414
|
toArray3() {
|
|
374
|
-
return [this.
|
|
415
|
+
return [this._x, this._y, this._z];
|
|
375
416
|
}
|
|
376
417
|
|
|
377
418
|
/**
|
|
@@ -380,7 +421,7 @@ export class Vec4 {
|
|
|
380
421
|
* @returns {string}
|
|
381
422
|
*/
|
|
382
423
|
toString(precision = 3) {
|
|
383
|
-
return `Vec4(${this.
|
|
424
|
+
return `Vec4(${this._x.toFixed(precision)}, ${this._y.toFixed(precision)}, ${this._z.toFixed(precision)}, ${this._w.toFixed(precision)})`;
|
|
384
425
|
}
|
|
385
426
|
|
|
386
427
|
/**
|
|
@@ -388,7 +429,7 @@ export class Vec4 {
|
|
|
388
429
|
* @returns {object}
|
|
389
430
|
*/
|
|
390
431
|
toJSON() {
|
|
391
|
-
return { x: this.
|
|
432
|
+
return { x: this._x, y: this._y, z: this._z, w: this._w };
|
|
392
433
|
}
|
|
393
434
|
|
|
394
435
|
// Static factory methods for common vectors
|
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
|
|
7
7
|
import { GeometryLibrary } from '../geometry/GeometryLibrary.js';
|
|
8
8
|
|
|
9
|
+
// Role-specific intensity values for 5-layer canvas architecture.
|
|
10
|
+
// IMPORTANT: Must stay in sync with shader epsilon comparisons in the fragment shader
|
|
11
|
+
// at the "LAYER-BY-LAYER COLOR SYSTEM" section (search for layerIndex).
|
|
12
|
+
const ROLE_INTENSITIES = {
|
|
13
|
+
'background': 0.4,
|
|
14
|
+
'shadow': 0.6,
|
|
15
|
+
'content': 1.0,
|
|
16
|
+
'highlight': 1.3,
|
|
17
|
+
'accent': 1.6
|
|
18
|
+
};
|
|
19
|
+
|
|
9
20
|
export class QuantumHolographicVisualizer {
|
|
10
21
|
constructor(canvasIdOrElement, role, reactivity, variant) {
|
|
11
22
|
this.canvas = (canvasIdOrElement instanceof HTMLCanvasElement)
|
|
@@ -14,6 +25,7 @@ export class QuantumHolographicVisualizer {
|
|
|
14
25
|
this.role = role;
|
|
15
26
|
this.reactivity = reactivity;
|
|
16
27
|
this.variant = variant;
|
|
28
|
+
this._canvasLabel = typeof canvasIdOrElement === 'string' ? canvasIdOrElement : canvasIdOrElement?.id || 'unknown';
|
|
17
29
|
|
|
18
30
|
// CRITICAL FIX: Define contextOptions as instance property to match SmartCanvasPool
|
|
19
31
|
this.contextOptions = {
|
|
@@ -34,9 +46,9 @@ export class QuantumHolographicVisualizer {
|
|
|
34
46
|
this.canvas.getContext('experimental-webgl', this.contextOptions);
|
|
35
47
|
|
|
36
48
|
if (!this.gl) {
|
|
37
|
-
console.error(`WebGL not supported for ${
|
|
49
|
+
console.error(`WebGL not supported for ${this._canvasLabel}`);
|
|
38
50
|
if (window.mobileDebug) {
|
|
39
|
-
window.mobileDebug.log(`❌ ${
|
|
51
|
+
window.mobileDebug.log(`❌ ${this._canvasLabel}: WebGL context creation failed`);
|
|
40
52
|
}
|
|
41
53
|
// Show user-friendly error instead of white screen
|
|
42
54
|
this.showWebGLError();
|
|
@@ -44,7 +56,7 @@ export class QuantumHolographicVisualizer {
|
|
|
44
56
|
} else {
|
|
45
57
|
if (window.mobileDebug) {
|
|
46
58
|
const version = this.gl.getParameter(this.gl.VERSION);
|
|
47
|
-
window.mobileDebug.log(`✅ ${
|
|
59
|
+
window.mobileDebug.log(`✅ ${this._canvasLabel}: WebGL context created - ${version}`);
|
|
48
60
|
}
|
|
49
61
|
}
|
|
50
62
|
|
|
@@ -59,15 +71,15 @@ export class QuantumHolographicVisualizer {
|
|
|
59
71
|
this._onContextLost = (e) => {
|
|
60
72
|
e.preventDefault();
|
|
61
73
|
this._contextLost = true;
|
|
62
|
-
console.warn(`WebGL context lost for ${
|
|
74
|
+
console.warn(`WebGL context lost for ${this._canvasLabel}`);
|
|
63
75
|
};
|
|
64
76
|
this._onContextRestored = () => {
|
|
65
|
-
console.log(`WebGL context restored for ${
|
|
77
|
+
console.log(`WebGL context restored for ${this._canvasLabel}`);
|
|
66
78
|
this._contextLost = false;
|
|
67
79
|
try {
|
|
68
80
|
this.init();
|
|
69
81
|
} catch (err) {
|
|
70
|
-
console.error(`Failed to reinit after context restore for ${
|
|
82
|
+
console.error(`Failed to reinit after context restore for ${this._canvasLabel}:`, err);
|
|
71
83
|
}
|
|
72
84
|
};
|
|
73
85
|
this.canvas.addEventListener('webglcontextlost', this._onContextLost);
|
|
@@ -688,11 +700,12 @@ void main() {
|
|
|
688
700
|
|
|
689
701
|
// LAYER-BY-LAYER COLOR SYSTEM with user hue/saturation/intensity controls
|
|
690
702
|
// Determine canvas layer from role/variant (0=background, 1=shadow, 2=content, 3=highlight, 4=accent)
|
|
703
|
+
// Values must match ROLE_INTENSITIES in JS: bg=0.4, shadow=0.6, content=1.0, highlight=1.3, accent=1.6
|
|
691
704
|
int layerIndex = 0;
|
|
692
|
-
if (u_roleIntensity
|
|
693
|
-
else if (u_roleIntensity
|
|
694
|
-
else if (u_roleIntensity
|
|
695
|
-
else if (u_roleIntensity
|
|
705
|
+
if (abs(u_roleIntensity - 0.6) < 0.05) layerIndex = 1; // shadow layer
|
|
706
|
+
else if (abs(u_roleIntensity - 1.0) < 0.05) layerIndex = 2; // content layer
|
|
707
|
+
else if (abs(u_roleIntensity - 1.3) < 0.05) layerIndex = 3; // highlight layer
|
|
708
|
+
else if (abs(u_roleIntensity - 1.6) < 0.05) layerIndex = 4; // accent layer
|
|
696
709
|
|
|
697
710
|
// Get layer-specific base color using user hue/saturation controls
|
|
698
711
|
float colorTime = timeSpeed * 2.0 + value * 3.0;
|
|
@@ -1016,15 +1029,6 @@ void main() {
|
|
|
1016
1029
|
this._renderParamsLogged = true;
|
|
1017
1030
|
}
|
|
1018
1031
|
|
|
1019
|
-
// Role-specific intensity for quantum effects
|
|
1020
|
-
const roleIntensities = {
|
|
1021
|
-
'background': 0.4,
|
|
1022
|
-
'shadow': 0.6,
|
|
1023
|
-
'content': 1.0,
|
|
1024
|
-
'highlight': 1.3,
|
|
1025
|
-
'accent': 1.6
|
|
1026
|
-
};
|
|
1027
|
-
|
|
1028
1032
|
const time = Date.now() - this.startTime;
|
|
1029
1033
|
|
|
1030
1034
|
// Set uniforms
|
|
@@ -1068,7 +1072,7 @@ void main() {
|
|
|
1068
1072
|
this.gl.uniform1f(this.uniforms.rot4dZW, this.params.rot4dZW || 0.0);
|
|
1069
1073
|
this.gl.uniform1f(this.uniforms.mouseIntensity, this.mouseIntensity);
|
|
1070
1074
|
this.gl.uniform1f(this.uniforms.clickIntensity, this.clickIntensity);
|
|
1071
|
-
this.gl.uniform1f(this.uniforms.roleIntensity,
|
|
1075
|
+
this.gl.uniform1f(this.uniforms.roleIntensity, ROLE_INTENSITIES[this.role] || 1.0);
|
|
1072
1076
|
this.gl.uniform1f(this.uniforms.breath, this.params.breath || 0.0);
|
|
1073
1077
|
|
|
1074
1078
|
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
|
|
@@ -199,6 +199,44 @@ export class ShaderLoader {
|
|
|
199
199
|
return results;
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Resolve #include directives in shader source.
|
|
204
|
+
* GLSL: #include "common/rotation4d.glsl"
|
|
205
|
+
* WGSL: // @include "common/rotation4d.wgsl"
|
|
206
|
+
*
|
|
207
|
+
* Includes are resolved from the loader's cache (call loadCommonLibrary() first).
|
|
208
|
+
* Non-recursive — only resolves one level of includes.
|
|
209
|
+
*
|
|
210
|
+
* @param {string} source - Shader source with include directives
|
|
211
|
+
* @returns {string} Resolved shader source
|
|
212
|
+
*/
|
|
213
|
+
resolveIncludes(source) {
|
|
214
|
+
if (!source) return source;
|
|
215
|
+
|
|
216
|
+
// GLSL: #include "path"
|
|
217
|
+
// WGSL: // @include "path"
|
|
218
|
+
const includeRegex = /(?:^|\n)\s*(?:#include|\/\/\s*@include)\s+"([^"]+)"\s*(?:\n|$)/g;
|
|
219
|
+
|
|
220
|
+
return source.replace(includeRegex, (match, path) => {
|
|
221
|
+
const cached = this._cache.get(path);
|
|
222
|
+
if (cached) {
|
|
223
|
+
return '\n// --- included from ' + path + ' ---\n' + cached + '\n// --- end ' + path + ' ---\n';
|
|
224
|
+
}
|
|
225
|
+
console.warn(`ShaderLoader: Include not found in cache: "${path}" — load it first via loadCommonLibrary()`);
|
|
226
|
+
return match; // Leave directive in place if not found
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Load a shader file and resolve includes.
|
|
232
|
+
* @param {string} relativePath
|
|
233
|
+
* @returns {Promise<string|null>}
|
|
234
|
+
*/
|
|
235
|
+
async loadAndResolve(relativePath) {
|
|
236
|
+
const source = await this.load(relativePath);
|
|
237
|
+
return source ? this.resolveIncludes(source) : null;
|
|
238
|
+
}
|
|
239
|
+
|
|
202
240
|
/**
|
|
203
241
|
* Clear all cached shaders.
|
|
204
242
|
*/
|
|
@@ -384,10 +384,10 @@ export const ShaderLib = {
|
|
|
384
384
|
mat4 rotateXZ(float angle) {
|
|
385
385
|
float c = cos(angle), s = sin(angle);
|
|
386
386
|
return mat4(
|
|
387
|
-
c, 0,
|
|
388
|
-
0, 1,
|
|
389
|
-
|
|
390
|
-
0, 0,
|
|
387
|
+
c, 0, s, 0,
|
|
388
|
+
0, 1, 0, 0,
|
|
389
|
+
-s, 0, c, 0,
|
|
390
|
+
0, 0, 0, 1
|
|
391
391
|
);
|
|
392
392
|
}
|
|
393
393
|
|
|
@@ -25,7 +25,7 @@ import { createWebGPUBackend, isWebGPUSupported, WGSLShaderLib } from './backend
|
|
|
25
25
|
* @returns {Float32Array}
|
|
26
26
|
*/
|
|
27
27
|
function packVIB3Uniforms(uniforms) {
|
|
28
|
-
// Total:
|
|
28
|
+
// Total: 33 floats (indices 0-32) = 132 bytes → padded to 256 bytes in buffer
|
|
29
29
|
const data = new Float32Array(64); // 256 bytes
|
|
30
30
|
|
|
31
31
|
data[0] = uniforms.u_time || 0;
|
|
@@ -152,10 +152,14 @@ struct VIB3Uniforms {
|
|
|
152
152
|
layerScale: f32,
|
|
153
153
|
layerOpacity: f32,
|
|
154
154
|
_pad1: f32,
|
|
155
|
-
|
|
155
|
+
layerColorR: f32,
|
|
156
|
+
layerColorG: f32,
|
|
157
|
+
layerColorB: f32,
|
|
156
158
|
densityMult: f32,
|
|
157
159
|
speedMult: f32,
|
|
158
|
-
|
|
160
|
+
|
|
161
|
+
// Vitality
|
|
162
|
+
breath: f32,
|
|
159
163
|
};
|
|
160
164
|
`;
|
|
161
165
|
|
|
@@ -178,9 +182,9 @@ fn rotateXZ(angle: f32) -> mat4x4<f32> {
|
|
|
178
182
|
let c = cos(angle);
|
|
179
183
|
let s = sin(angle);
|
|
180
184
|
return mat4x4<f32>(
|
|
181
|
-
vec4<f32>(c, 0.0,
|
|
185
|
+
vec4<f32>( c, 0.0, s, 0.0),
|
|
182
186
|
vec4<f32>(0.0, 1.0, 0.0, 0.0),
|
|
183
|
-
vec4<f32>(s, 0.0, c, 0.0),
|
|
187
|
+
vec4<f32>(-s, 0.0, c, 0.0),
|
|
184
188
|
vec4<f32>(0.0, 0.0, 0.0, 1.0)
|
|
185
189
|
);
|
|
186
190
|
}
|
|
@@ -53,6 +53,71 @@ float hypertetrahedronCore(vec4 p, float baseType) {
|
|
|
53
53
|
return max(baseShape, tetraField);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
// ── Polytope Core Warp Functions ──
|
|
57
|
+
// Requires: rotation matrices from rotation4d.glsl, project4Dto3D, and u_* uniforms
|
|
58
|
+
|
|
59
|
+
vec3 warpHypersphereCore(vec3 p, int geometryIndex, vec2 mouseDelta) {
|
|
60
|
+
float radius = length(p);
|
|
61
|
+
float morphBlend = clamp(u_morphFactor * 0.6 + (u_dimension - 3.0) * 0.25, 0.0, 2.0);
|
|
62
|
+
float w = sin(radius * (1.3 + float(geometryIndex) * 0.12) + u_time * 0.0008 * u_speed);
|
|
63
|
+
w *= (0.4 + morphBlend * 0.45);
|
|
64
|
+
|
|
65
|
+
vec4 p4d = vec4(p * (1.0 + morphBlend * 0.2), w);
|
|
66
|
+
p4d = rotateXY(u_rot4dXY) * p4d;
|
|
67
|
+
p4d = rotateXZ(u_rot4dXZ) * p4d;
|
|
68
|
+
p4d = rotateYZ(u_rot4dYZ) * p4d;
|
|
69
|
+
p4d = rotateXW(u_rot4dXW) * p4d;
|
|
70
|
+
p4d = rotateYW(u_rot4dYW) * p4d;
|
|
71
|
+
p4d = rotateZW(u_rot4dZW) * p4d;
|
|
72
|
+
|
|
73
|
+
vec3 projected = project4Dto3D(p4d);
|
|
74
|
+
return mix(p, projected, clamp(0.45 + morphBlend * 0.35, 0.0, 1.0));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
vec3 warpHypertetraCore(vec3 p, int geometryIndex, vec2 mouseDelta) {
|
|
78
|
+
vec3 c1 = normalize(vec3(1.0, 1.0, 1.0));
|
|
79
|
+
vec3 c2 = normalize(vec3(-1.0, -1.0, 1.0));
|
|
80
|
+
vec3 c3 = normalize(vec3(-1.0, 1.0, -1.0));
|
|
81
|
+
vec3 c4 = normalize(vec3(1.0, -1.0, -1.0));
|
|
82
|
+
|
|
83
|
+
float morphBlend = clamp(u_morphFactor * 0.8 + (u_dimension - 3.0) * 0.2, 0.0, 2.0);
|
|
84
|
+
float basisMix = dot(p, c1) * 0.14 + dot(p, c2) * 0.1 + dot(p, c3) * 0.08;
|
|
85
|
+
float w = sin(basisMix * 5.5 + u_time * 0.0009 * u_speed);
|
|
86
|
+
w *= cos(dot(p, c4) * 4.2 - u_time * 0.0007 * u_speed);
|
|
87
|
+
w *= (0.5 + morphBlend * 0.4);
|
|
88
|
+
|
|
89
|
+
vec3 offset = vec3(dot(p, c1), dot(p, c2), dot(p, c3)) * 0.1 * morphBlend;
|
|
90
|
+
vec4 p4d = vec4(p + offset, w);
|
|
91
|
+
p4d = rotateXY(u_rot4dXY) * p4d;
|
|
92
|
+
p4d = rotateXZ(u_rot4dXZ) * p4d;
|
|
93
|
+
p4d = rotateYZ(u_rot4dYZ) * p4d;
|
|
94
|
+
p4d = rotateXW(u_rot4dXW) * p4d;
|
|
95
|
+
p4d = rotateYW(u_rot4dYW) * p4d;
|
|
96
|
+
p4d = rotateZW(u_rot4dZW) * p4d;
|
|
97
|
+
|
|
98
|
+
vec3 projected = project4Dto3D(p4d);
|
|
99
|
+
float planeInfluence = min(min(abs(dot(p, c1)), abs(dot(p, c2))),
|
|
100
|
+
min(abs(dot(p, c3)), abs(dot(p, c4))));
|
|
101
|
+
vec3 blended = mix(p, projected, clamp(0.45 + morphBlend * 0.35, 0.0, 1.0));
|
|
102
|
+
return mix(blended, blended * (1.0 - planeInfluence * 0.55), 0.2 + morphBlend * 0.2);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
vec3 applyCoreWarp(vec3 p, float geometryType, vec2 mouseDelta) {
|
|
106
|
+
float totalBase = 8.0;
|
|
107
|
+
float coreFloat = floor(geometryType / totalBase);
|
|
108
|
+
int coreIndex = int(clamp(coreFloat, 0.0, 2.0));
|
|
109
|
+
float baseGeomFloat = geometryType - floor(geometryType / totalBase) * totalBase;
|
|
110
|
+
int geometryIndex = int(clamp(floor(baseGeomFloat + 0.5), 0.0, totalBase - 1.0));
|
|
111
|
+
|
|
112
|
+
if (coreIndex == 1) {
|
|
113
|
+
return warpHypersphereCore(p, geometryIndex, mouseDelta);
|
|
114
|
+
}
|
|
115
|
+
if (coreIndex == 2) {
|
|
116
|
+
return warpHypertetraCore(p, geometryIndex, mouseDelta);
|
|
117
|
+
}
|
|
118
|
+
return p;
|
|
119
|
+
}
|
|
120
|
+
|
|
56
121
|
// Main geometry dispatcher (0-23)
|
|
57
122
|
float geometry(vec4 p, float type) {
|
|
58
123
|
if (type < 8.0) {
|