@poolzin/pool-bot 2026.1.37 → 2026.1.39
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 +9 -98
- package/dist/agents/tools/memory-tool.js +1 -2
- package/dist/agents/workspace.js +1 -5
- package/dist/build-info.json +3 -3
- package/dist/channels/plugins/agent-tools/whatsapp-login.js +1 -17
- package/dist/commands/doctor-state-integrity.js +2 -14
- package/dist/config/types.js +0 -1
- package/dist/config/zod-schema.js +0 -6
- package/dist/discord/monitor/message-handler.process.js +6 -4
- package/dist/gateway/client.js +0 -14
- package/dist/gateway/server.impl.js +0 -4
- package/dist/memory/index.js +0 -5
- package/dist/memory/manager.js +2 -25
- package/dist/slack/monitor/message-handler/prepare.js +10 -4
- package/dist/slack/monitor/slash.js +10 -4
- package/extensions/memory-core/package.json +0 -3
- package/package.json +3 -2
- package/skills/webgpu-threejs-tsl/REFERENCE.md +0 -283
- package/skills/webgpu-threejs-tsl/SKILL.md +0 -91
- package/skills/webgpu-threejs-tsl/docs/compute-shaders.md +0 -404
- package/skills/webgpu-threejs-tsl/docs/core-concepts.md +0 -453
- package/skills/webgpu-threejs-tsl/docs/materials.md +0 -353
- package/skills/webgpu-threejs-tsl/docs/post-processing.md +0 -434
- package/skills/webgpu-threejs-tsl/docs/wgsl-integration.md +0 -324
- package/skills/webgpu-threejs-tsl/examples/basic-setup.js +0 -87
- package/skills/webgpu-threejs-tsl/examples/custom-material.js +0 -170
- package/skills/webgpu-threejs-tsl/examples/earth-shader.js +0 -292
- package/skills/webgpu-threejs-tsl/examples/particle-system.js +0 -259
- package/skills/webgpu-threejs-tsl/examples/post-processing.js +0 -199
- package/skills/webgpu-threejs-tsl/templates/compute-shader.js +0 -305
- package/skills/webgpu-threejs-tsl/templates/webgpu-project.js +0 -276
|
@@ -1,324 +0,0 @@
|
|
|
1
|
-
# WGSL Integration
|
|
2
|
-
|
|
3
|
-
TSL allows embedding raw WGSL (WebGPU Shading Language) code when you need direct GPU control.
|
|
4
|
-
|
|
5
|
-
## wgslFn - Custom WGSL Functions
|
|
6
|
-
|
|
7
|
-
### Basic Usage
|
|
8
|
-
|
|
9
|
-
```javascript
|
|
10
|
-
import { wgslFn, float, vec3 } from 'three/tsl';
|
|
11
|
-
|
|
12
|
-
// Define WGSL function
|
|
13
|
-
const gammaCorrect = wgslFn(`
|
|
14
|
-
fn gammaCorrect(color: vec3<f32>, gamma: f32) -> vec3<f32> {
|
|
15
|
-
return pow(color, vec3<f32>(1.0 / gamma));
|
|
16
|
-
}
|
|
17
|
-
`);
|
|
18
|
-
|
|
19
|
-
// Use in TSL
|
|
20
|
-
material.colorNode = gammaCorrect(inputColor, float(2.2));
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### Function with Multiple Parameters
|
|
24
|
-
|
|
25
|
-
```javascript
|
|
26
|
-
const blendColors = wgslFn(`
|
|
27
|
-
fn blendColors(a: vec3<f32>, b: vec3<f32>, t: f32) -> vec3<f32> {
|
|
28
|
-
return mix(a, b, t);
|
|
29
|
-
}
|
|
30
|
-
`);
|
|
31
|
-
|
|
32
|
-
material.colorNode = blendColors(colorA, colorB, blendFactor);
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### Advanced Math Functions
|
|
36
|
-
|
|
37
|
-
```javascript
|
|
38
|
-
const fresnelSchlick = wgslFn(`
|
|
39
|
-
fn fresnelSchlick(cosTheta: f32, F0: vec3<f32>) -> vec3<f32> {
|
|
40
|
-
return F0 + (vec3<f32>(1.0) - F0) * pow(1.0 - cosTheta, 5.0);
|
|
41
|
-
}
|
|
42
|
-
`);
|
|
43
|
-
|
|
44
|
-
const GGX = wgslFn(`
|
|
45
|
-
fn distributionGGX(N: vec3<f32>, H: vec3<f32>, roughness: f32) -> f32 {
|
|
46
|
-
let a = roughness * roughness;
|
|
47
|
-
let a2 = a * a;
|
|
48
|
-
let NdotH = max(dot(N, H), 0.0);
|
|
49
|
-
let NdotH2 = NdotH * NdotH;
|
|
50
|
-
|
|
51
|
-
let num = a2;
|
|
52
|
-
let denom = (NdotH2 * (a2 - 1.0) + 1.0);
|
|
53
|
-
denom = 3.14159265359 * denom * denom;
|
|
54
|
-
|
|
55
|
-
return num / denom;
|
|
56
|
-
}
|
|
57
|
-
`);
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### Noise Functions
|
|
61
|
-
|
|
62
|
-
```javascript
|
|
63
|
-
const simplexNoise = wgslFn(`
|
|
64
|
-
fn mod289(x: vec3<f32>) -> vec3<f32> {
|
|
65
|
-
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
fn permute(x: vec3<f32>) -> vec3<f32> {
|
|
69
|
-
return mod289(((x * 34.0) + 1.0) * x);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
fn snoise(v: vec2<f32>) -> f32 {
|
|
73
|
-
let C = vec4<f32>(
|
|
74
|
-
0.211324865405187,
|
|
75
|
-
0.366025403784439,
|
|
76
|
-
-0.577350269189626,
|
|
77
|
-
0.024390243902439
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
var i = floor(v + dot(v, C.yy));
|
|
81
|
-
let x0 = v - i + dot(i, C.xx);
|
|
82
|
-
|
|
83
|
-
var i1: vec2<f32>;
|
|
84
|
-
if (x0.x > x0.y) {
|
|
85
|
-
i1 = vec2<f32>(1.0, 0.0);
|
|
86
|
-
} else {
|
|
87
|
-
i1 = vec2<f32>(0.0, 1.0);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
var x12 = x0.xyxy + C.xxzz;
|
|
91
|
-
x12 = vec4<f32>(x12.xy - i1, x12.zw);
|
|
92
|
-
|
|
93
|
-
i = mod289(vec3<f32>(i, 0.0)).xy;
|
|
94
|
-
let p = permute(permute(i.y + vec3<f32>(0.0, i1.y, 1.0)) + i.x + vec3<f32>(0.0, i1.x, 1.0));
|
|
95
|
-
|
|
96
|
-
var m = max(vec3<f32>(0.5) - vec3<f32>(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), vec3<f32>(0.0));
|
|
97
|
-
m = m * m;
|
|
98
|
-
m = m * m;
|
|
99
|
-
|
|
100
|
-
let x = 2.0 * fract(p * C.www) - 1.0;
|
|
101
|
-
let h = abs(x) - 0.5;
|
|
102
|
-
let ox = floor(x + 0.5);
|
|
103
|
-
let a0 = x - ox;
|
|
104
|
-
|
|
105
|
-
m = m * (1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h));
|
|
106
|
-
|
|
107
|
-
let g = vec3<f32>(
|
|
108
|
-
a0.x * x0.x + h.x * x0.y,
|
|
109
|
-
a0.y * x12.x + h.y * x12.y,
|
|
110
|
-
a0.z * x12.z + h.z * x12.w
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
return 130.0 * dot(m, g);
|
|
114
|
-
}
|
|
115
|
-
`);
|
|
116
|
-
|
|
117
|
-
// Use noise
|
|
118
|
-
const noiseValue = simplexNoise(uv().mul(10.0));
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### FBM (Fractal Brownian Motion)
|
|
122
|
-
|
|
123
|
-
```javascript
|
|
124
|
-
const fbm = wgslFn(`
|
|
125
|
-
fn fbm(p: vec2<f32>, octaves: i32) -> f32 {
|
|
126
|
-
var value = 0.0;
|
|
127
|
-
var amplitude = 0.5;
|
|
128
|
-
var frequency = 1.0;
|
|
129
|
-
var pos = p;
|
|
130
|
-
|
|
131
|
-
for (var i = 0; i < octaves; i = i + 1) {
|
|
132
|
-
value = value + amplitude * snoise(pos * frequency);
|
|
133
|
-
amplitude = amplitude * 0.5;
|
|
134
|
-
frequency = frequency * 2.0;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return value;
|
|
138
|
-
}
|
|
139
|
-
`);
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## WGSL Types Reference
|
|
143
|
-
|
|
144
|
-
### Scalar Types
|
|
145
|
-
```wgsl
|
|
146
|
-
bool // Boolean
|
|
147
|
-
i32 // 32-bit signed integer
|
|
148
|
-
u32 // 32-bit unsigned integer
|
|
149
|
-
f32 // 32-bit float
|
|
150
|
-
f16 // 16-bit float (if enabled)
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### Vector Types
|
|
154
|
-
```wgsl
|
|
155
|
-
vec2<f32> // 2D float vector
|
|
156
|
-
vec3<f32> // 3D float vector
|
|
157
|
-
vec4<f32> // 4D float vector
|
|
158
|
-
vec2<i32> // 2D integer vector
|
|
159
|
-
vec2<u32> // 2D unsigned integer vector
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### Matrix Types
|
|
163
|
-
```wgsl
|
|
164
|
-
mat2x2<f32> // 2x2 matrix
|
|
165
|
-
mat3x3<f32> // 3x3 matrix
|
|
166
|
-
mat4x4<f32> // 4x4 matrix
|
|
167
|
-
mat2x3<f32> // 2 columns, 3 rows
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Texture Types
|
|
171
|
-
```wgsl
|
|
172
|
-
texture_2d<f32>
|
|
173
|
-
texture_3d<f32>
|
|
174
|
-
texture_cube<f32>
|
|
175
|
-
texture_storage_2d<rgba8unorm, write>
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
## WGSL Syntax Reference
|
|
179
|
-
|
|
180
|
-
### Variables
|
|
181
|
-
```wgsl
|
|
182
|
-
let x = 1.0; // Immutable
|
|
183
|
-
var y = 2.0; // Mutable
|
|
184
|
-
const PI = 3.14159; // Compile-time constant
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### Control Flow
|
|
188
|
-
```wgsl
|
|
189
|
-
// If-else
|
|
190
|
-
if (condition) {
|
|
191
|
-
// ...
|
|
192
|
-
} else if (other) {
|
|
193
|
-
// ...
|
|
194
|
-
} else {
|
|
195
|
-
// ...
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// For loop
|
|
199
|
-
for (var i = 0; i < 10; i = i + 1) {
|
|
200
|
-
// ...
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// While loop
|
|
204
|
-
while (condition) {
|
|
205
|
-
// ...
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Switch
|
|
209
|
-
switch (value) {
|
|
210
|
-
case 0: { /* ... */ }
|
|
211
|
-
case 1, 2: { /* ... */ }
|
|
212
|
-
default: { /* ... */ }
|
|
213
|
-
}
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
### Built-in Functions
|
|
217
|
-
```wgsl
|
|
218
|
-
// Math
|
|
219
|
-
abs(x), sign(x), floor(x), ceil(x), round(x)
|
|
220
|
-
fract(x), trunc(x)
|
|
221
|
-
min(a, b), max(a, b), clamp(x, lo, hi)
|
|
222
|
-
mix(a, b, t), step(edge, x), smoothstep(lo, hi, x)
|
|
223
|
-
sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y, x)
|
|
224
|
-
pow(x, y), exp(x), log(x), exp2(x), log2(x)
|
|
225
|
-
sqrt(x), inverseSqrt(x)
|
|
226
|
-
|
|
227
|
-
// Vector
|
|
228
|
-
length(v), distance(a, b)
|
|
229
|
-
dot(a, b), cross(a, b)
|
|
230
|
-
normalize(v), faceForward(n, i, nref)
|
|
231
|
-
reflect(i, n), refract(i, n, eta)
|
|
232
|
-
|
|
233
|
-
// Matrix
|
|
234
|
-
transpose(m), determinant(m)
|
|
235
|
-
|
|
236
|
-
// Texture
|
|
237
|
-
textureSample(t, s, coord)
|
|
238
|
-
textureLoad(t, coord, level)
|
|
239
|
-
textureStore(t, coord, value)
|
|
240
|
-
textureDimensions(t)
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
## Combining TSL and WGSL
|
|
244
|
-
|
|
245
|
-
### TSL Wrapper for WGSL
|
|
246
|
-
|
|
247
|
-
```javascript
|
|
248
|
-
import { Fn, wgslFn, float, vec2, vec3 } from 'three/tsl';
|
|
249
|
-
|
|
250
|
-
// WGSL implementation
|
|
251
|
-
const wgslNoise = wgslFn(`
|
|
252
|
-
fn noise2d(p: vec2<f32>) -> f32 {
|
|
253
|
-
return fract(sin(dot(p, vec2<f32>(12.9898, 78.233))) * 43758.5453);
|
|
254
|
-
}
|
|
255
|
-
`);
|
|
256
|
-
|
|
257
|
-
// TSL wrapper with nice API
|
|
258
|
-
const noise = Fn(([position, scale = 1.0]) => {
|
|
259
|
-
return wgslNoise(position.xy.mul(scale));
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
// Use
|
|
263
|
-
material.colorNode = vec3(noise(positionWorld, 10.0));
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### Hybrid Approach
|
|
267
|
-
|
|
268
|
-
```javascript
|
|
269
|
-
// Complex math in WGSL
|
|
270
|
-
const complexMath = wgslFn(`
|
|
271
|
-
fn complexOperation(a: vec3<f32>, b: vec3<f32>, t: f32) -> vec3<f32> {
|
|
272
|
-
let blended = mix(a, b, t);
|
|
273
|
-
let rotated = vec3<f32>(
|
|
274
|
-
blended.x * cos(t) - blended.y * sin(t),
|
|
275
|
-
blended.x * sin(t) + blended.y * cos(t),
|
|
276
|
-
blended.z
|
|
277
|
-
);
|
|
278
|
-
return normalize(rotated);
|
|
279
|
-
}
|
|
280
|
-
`);
|
|
281
|
-
|
|
282
|
-
// Simple logic in TSL
|
|
283
|
-
const finalColor = Fn(() => {
|
|
284
|
-
const base = texture(diffuseMap).rgb;
|
|
285
|
-
const processed = complexMath(base, vec3(1, 0, 0), time);
|
|
286
|
-
return mix(base, processed, oscSine(time));
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
material.colorNode = finalColor();
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
## Performance Tips
|
|
293
|
-
|
|
294
|
-
### Avoid Branching When Possible
|
|
295
|
-
```wgsl
|
|
296
|
-
// Instead of:
|
|
297
|
-
if (x > 0.5) {
|
|
298
|
-
result = a;
|
|
299
|
-
} else {
|
|
300
|
-
result = b;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// Use:
|
|
304
|
-
result = mix(b, a, step(0.5, x));
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### Use Local Variables
|
|
308
|
-
```wgsl
|
|
309
|
-
fn compute(p: vec2<f32>) -> f32 {
|
|
310
|
-
// Cache repeated calculations
|
|
311
|
-
let p2 = p * p;
|
|
312
|
-
let p4 = p2 * p2;
|
|
313
|
-
return p2.x + p2.y + p4.x * p4.y;
|
|
314
|
-
}
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
### Minimize Texture Samples
|
|
318
|
-
```wgsl
|
|
319
|
-
// Sample once, use multiple times
|
|
320
|
-
let sample = textureSample(tex, sampler, uv);
|
|
321
|
-
let r = sample.r;
|
|
322
|
-
let g = sample.g;
|
|
323
|
-
let b = sample.b;
|
|
324
|
-
```
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Basic WebGPU Three.js Setup
|
|
3
|
-
*
|
|
4
|
-
* Minimal example showing WebGPU renderer initialization
|
|
5
|
-
* with a simple animated mesh using TSL.
|
|
6
|
-
*
|
|
7
|
-
* Based on Three.js examples (MIT License)
|
|
8
|
-
* https://github.com/mrdoob/three.js
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import * as THREE from 'three/webgpu';
|
|
12
|
-
import { color, time, oscSine, positionLocal, normalWorld } from 'three/tsl';
|
|
13
|
-
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
|
14
|
-
|
|
15
|
-
let camera, scene, renderer, controls;
|
|
16
|
-
|
|
17
|
-
async function init() {
|
|
18
|
-
// Camera
|
|
19
|
-
camera = new THREE.PerspectiveCamera(
|
|
20
|
-
70,
|
|
21
|
-
window.innerWidth / window.innerHeight,
|
|
22
|
-
0.1,
|
|
23
|
-
100
|
|
24
|
-
);
|
|
25
|
-
camera.position.z = 4;
|
|
26
|
-
|
|
27
|
-
// Scene
|
|
28
|
-
scene = new THREE.Scene();
|
|
29
|
-
scene.background = new THREE.Color(0x111111);
|
|
30
|
-
|
|
31
|
-
// Lighting
|
|
32
|
-
const ambientLight = new THREE.AmbientLight(0x404040);
|
|
33
|
-
scene.add(ambientLight);
|
|
34
|
-
|
|
35
|
-
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
|
|
36
|
-
directionalLight.position.set(5, 5, 5);
|
|
37
|
-
scene.add(directionalLight);
|
|
38
|
-
|
|
39
|
-
// Create mesh with TSL material
|
|
40
|
-
const geometry = new THREE.TorusKnotGeometry(1, 0.3, 128, 32);
|
|
41
|
-
const material = new THREE.MeshStandardNodeMaterial();
|
|
42
|
-
|
|
43
|
-
// Animated color using TSL
|
|
44
|
-
material.colorNode = color(0x0088ff).mul(
|
|
45
|
-
oscSine(time.mul(0.5)).mul(0.5).add(0.5)
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
// Add slight position wobble
|
|
49
|
-
material.positionNode = positionLocal.add(
|
|
50
|
-
normalWorld.mul(oscSine(time.mul(2.0).add(positionLocal.y)).mul(0.05))
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
const mesh = new THREE.Mesh(geometry, material);
|
|
54
|
-
scene.add(mesh);
|
|
55
|
-
|
|
56
|
-
// Renderer
|
|
57
|
-
renderer = new THREE.WebGPURenderer({ antialias: true });
|
|
58
|
-
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
59
|
-
renderer.setPixelRatio(window.devicePixelRatio);
|
|
60
|
-
document.body.appendChild(renderer.domElement);
|
|
61
|
-
|
|
62
|
-
// Initialize WebGPU
|
|
63
|
-
await renderer.init();
|
|
64
|
-
|
|
65
|
-
// Controls
|
|
66
|
-
controls = new OrbitControls(camera, renderer.domElement);
|
|
67
|
-
controls.enableDamping = true;
|
|
68
|
-
|
|
69
|
-
// Handle resize
|
|
70
|
-
window.addEventListener('resize', onWindowResize);
|
|
71
|
-
|
|
72
|
-
// Start animation loop
|
|
73
|
-
renderer.setAnimationLoop(animate);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function onWindowResize() {
|
|
77
|
-
camera.aspect = window.innerWidth / window.innerHeight;
|
|
78
|
-
camera.updateProjectionMatrix();
|
|
79
|
-
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function animate() {
|
|
83
|
-
controls.update();
|
|
84
|
-
renderer.render(scene, camera);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
init();
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom TSL Material Example
|
|
3
|
-
*
|
|
4
|
-
* Demonstrates creating custom shader effects using TSL:
|
|
5
|
-
* - Fresnel rim lighting
|
|
6
|
-
* - Animated patterns
|
|
7
|
-
* - Dynamic displacement
|
|
8
|
-
*
|
|
9
|
-
* Based on Three.js examples (MIT License)
|
|
10
|
-
* https://github.com/mrdoob/three.js
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import * as THREE from 'three/webgpu';
|
|
14
|
-
import {
|
|
15
|
-
Fn,
|
|
16
|
-
color,
|
|
17
|
-
float,
|
|
18
|
-
vec2,
|
|
19
|
-
vec3,
|
|
20
|
-
uniform,
|
|
21
|
-
texture,
|
|
22
|
-
uv,
|
|
23
|
-
time,
|
|
24
|
-
mix,
|
|
25
|
-
smoothstep,
|
|
26
|
-
sin,
|
|
27
|
-
cos,
|
|
28
|
-
positionLocal,
|
|
29
|
-
positionWorld,
|
|
30
|
-
normalLocal,
|
|
31
|
-
normalWorld,
|
|
32
|
-
cameraPosition
|
|
33
|
-
} from 'three/tsl';
|
|
34
|
-
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
|
35
|
-
|
|
36
|
-
let camera, scene, renderer, controls;
|
|
37
|
-
let rimColor, patternScale, displacementStrength;
|
|
38
|
-
|
|
39
|
-
async function init() {
|
|
40
|
-
// Setup
|
|
41
|
-
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100);
|
|
42
|
-
camera.position.z = 3;
|
|
43
|
-
|
|
44
|
-
scene = new THREE.Scene();
|
|
45
|
-
scene.background = new THREE.Color(0x000000);
|
|
46
|
-
|
|
47
|
-
// Uniforms for runtime control
|
|
48
|
-
rimColor = uniform(new THREE.Color(0x00ffff));
|
|
49
|
-
patternScale = uniform(5.0);
|
|
50
|
-
displacementStrength = uniform(0.1);
|
|
51
|
-
|
|
52
|
-
// Create custom material
|
|
53
|
-
const material = createCustomMaterial();
|
|
54
|
-
|
|
55
|
-
// Mesh
|
|
56
|
-
const geometry = new THREE.IcosahedronGeometry(1, 64);
|
|
57
|
-
const mesh = new THREE.Mesh(geometry, material);
|
|
58
|
-
scene.add(mesh);
|
|
59
|
-
|
|
60
|
-
// Renderer
|
|
61
|
-
renderer = new THREE.WebGPURenderer({ antialias: true });
|
|
62
|
-
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
63
|
-
renderer.setPixelRatio(window.devicePixelRatio);
|
|
64
|
-
document.body.appendChild(renderer.domElement);
|
|
65
|
-
await renderer.init();
|
|
66
|
-
|
|
67
|
-
// Controls
|
|
68
|
-
controls = new OrbitControls(camera, renderer.domElement);
|
|
69
|
-
controls.enableDamping = true;
|
|
70
|
-
|
|
71
|
-
// Events
|
|
72
|
-
window.addEventListener('resize', onWindowResize);
|
|
73
|
-
|
|
74
|
-
// GUI (optional - requires lil-gui)
|
|
75
|
-
setupGUI();
|
|
76
|
-
|
|
77
|
-
renderer.setAnimationLoop(animate);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function createCustomMaterial() {
|
|
81
|
-
const material = new THREE.MeshStandardNodeMaterial();
|
|
82
|
-
|
|
83
|
-
// --- Fresnel Rim Effect ---
|
|
84
|
-
const fresnel = Fn(() => {
|
|
85
|
-
const viewDir = cameraPosition.sub(positionWorld).normalize();
|
|
86
|
-
const nDotV = normalWorld.dot(viewDir).saturate();
|
|
87
|
-
return float(1.0).sub(nDotV).pow(3.0);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// --- Animated Pattern ---
|
|
91
|
-
const animatedPattern = Fn(() => {
|
|
92
|
-
const uvCoord = uv().mul(patternScale);
|
|
93
|
-
const t = time.mul(0.5);
|
|
94
|
-
|
|
95
|
-
// Create animated wave pattern
|
|
96
|
-
const wave1 = sin(uvCoord.x.mul(10.0).add(t)).mul(0.5).add(0.5);
|
|
97
|
-
const wave2 = sin(uvCoord.y.mul(10.0).sub(t.mul(1.3))).mul(0.5).add(0.5);
|
|
98
|
-
const wave3 = sin(uvCoord.x.add(uvCoord.y).mul(7.0).add(t.mul(0.7))).mul(0.5).add(0.5);
|
|
99
|
-
|
|
100
|
-
return wave1.mul(wave2).mul(wave3);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// --- Displacement ---
|
|
104
|
-
const displacement = Fn(() => {
|
|
105
|
-
const pattern = animatedPattern();
|
|
106
|
-
return normalLocal.mul(pattern.mul(displacementStrength));
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Apply displacement
|
|
110
|
-
material.positionNode = positionLocal.add(displacement());
|
|
111
|
-
|
|
112
|
-
// --- Color ---
|
|
113
|
-
const baseColor = color(0x222244);
|
|
114
|
-
const highlightColor = color(0x4444ff);
|
|
115
|
-
|
|
116
|
-
// Mix colors based on pattern
|
|
117
|
-
const pattern = animatedPattern();
|
|
118
|
-
const surfaceColor = mix(baseColor, highlightColor, pattern);
|
|
119
|
-
|
|
120
|
-
material.colorNode = surfaceColor;
|
|
121
|
-
|
|
122
|
-
// --- Rim lighting ---
|
|
123
|
-
material.emissiveNode = rimColor.mul(fresnel());
|
|
124
|
-
|
|
125
|
-
// --- PBR properties ---
|
|
126
|
-
material.roughnessNode = float(0.3).add(pattern.mul(0.4));
|
|
127
|
-
material.metalnessNode = float(0.1);
|
|
128
|
-
|
|
129
|
-
return material;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function setupGUI() {
|
|
133
|
-
// Only setup if lil-gui is available
|
|
134
|
-
if (typeof window.GUI === 'undefined') {
|
|
135
|
-
console.log('Add lil-gui for interactive controls');
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const gui = new GUI();
|
|
140
|
-
const params = {
|
|
141
|
-
rimColor: '#00ffff',
|
|
142
|
-
patternScale: 5.0,
|
|
143
|
-
displacementStrength: 0.1
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
gui.addColor(params, 'rimColor').onChange((value) => {
|
|
147
|
-
rimColor.value.set(value);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
gui.add(params, 'patternScale', 1, 20).onChange((value) => {
|
|
151
|
-
patternScale.value = value;
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
gui.add(params, 'displacementStrength', 0, 0.5).onChange((value) => {
|
|
155
|
-
displacementStrength.value = value;
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function onWindowResize() {
|
|
160
|
-
camera.aspect = window.innerWidth / window.innerHeight;
|
|
161
|
-
camera.updateProjectionMatrix();
|
|
162
|
-
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function animate() {
|
|
166
|
-
controls.update();
|
|
167
|
-
renderer.render(scene, camera);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
init();
|