0
# Three Shading Language (TSL)
1
2
Three Shading Language (TSL) is a node-based shading system that provides a JavaScript-friendly syntax for creating custom materials and effects. TSL enables developers to write shaders using familiar JavaScript constructs while generating optimized GPU code for both WebGL and WebGPU renderers.
3
4
**Import:** TSL functionality is available via the dedicated TSL build:
5
6
```javascript
7
import {
8
color, vec3, vec4, float, int, bool,
9
uniform, attribute, varying, texture,
10
add, mul, sin, cos, normalize, dot,
11
mix, smoothstep, clamp, pow
12
} from 'three/tsl';
13
```
14
15
## Capabilities
16
17
### Core Node Types
18
19
Fundamental building blocks for creating shader node graphs with type-safe operations.
20
21
```javascript { .api }
22
/**
23
* Base class for all TSL nodes
24
*/
25
abstract class Node {
26
/** Node type identifier */
27
nodeType: string;
28
29
/** Node value type (float, vec3, etc.) */
30
type: string | null;
31
32
/** Unique identifier for this node */
33
uuid: string;
34
35
/**
36
* Get node hash for caching
37
* @returns Hash string
38
*/
39
getHash(): string;
40
41
/**
42
* Update node before rendering
43
* @param frame - Current render frame
44
*/
45
update(frame: NodeFrame): void;
46
47
/**
48
* Build node for specific renderer
49
* @param builder - Node builder context
50
* @returns Generated code string
51
*/
52
build(builder: NodeBuilder): string;
53
54
/**
55
* Analyze node dependencies
56
* @param builder - Node builder context
57
*/
58
analyze(builder: NodeBuilder): void;
59
60
/**
61
* Generate code for this node
62
* @param builder - Node builder context
63
* @returns Generated shader code
64
*/
65
generate(builder: NodeBuilder): string;
66
}
67
68
/**
69
* Create uniform input node
70
* @param value - Uniform value (number, Vector3, Color, etc.)
71
* @returns Uniform node
72
*/
73
declare function uniform(value: any): UniformNode;
74
75
/**
76
* Create vertex attribute input node
77
* @param name - Attribute name in geometry
78
* @param type - Attribute data type
79
* @returns Attribute node
80
*/
81
declare function attribute(name: string, type?: string): AttributeNode;
82
83
/**
84
* Create varying node for vertex-fragment communication
85
* @param node - Node to pass from vertex to fragment
86
* @param name - Optional varying name
87
* @returns Varying node
88
*/
89
declare function varying(node: Node, name?: string): VaryingNode;
90
```
91
92
### Vector and Scalar Types
93
94
Type-safe vector and scalar operations with automatic type inference and conversion.
95
96
```javascript { .api }
97
/**
98
* Create float/scalar node
99
* @param value - Numeric value or node
100
* @returns Float node
101
*/
102
declare function float(value: NodeRepresentation): FloatNode;
103
104
/**
105
* Create integer node
106
* @param value - Integer value or node
107
* @returns Integer node
108
*/
109
declare function int(value: NodeRepresentation): IntNode;
110
111
/**
112
* Create boolean node
113
* @param value - Boolean value or node
114
* @returns Boolean node
115
*/
116
declare function bool(value: NodeRepresentation): BoolNode;
117
118
/**
119
* Create 2D vector node
120
* @param x - X component (number/node) or Vector2
121
* @param y - Y component (number/node, optional if x is Vector2)
122
* @returns Vec2 node
123
*/
124
declare function vec2(x?: NodeRepresentation, y?: NodeRepresentation): Vec2Node;
125
126
/**
127
* Create 3D vector node
128
* @param x - X component (number/node) or Vector3
129
* @param y - Y component (number/node, optional if x is Vector3)
130
* @param z - Z component (number/node, optional if x is Vector3)
131
* @returns Vec3 node
132
*/
133
declare function vec3(x?: NodeRepresentation, y?: NodeRepresentation, z?: NodeRepresentation): Vec3Node;
134
135
/**
136
* Create 4D vector node
137
* @param x - X component (number/node) or Vector4
138
* @param y - Y component (number/node, optional if x is Vector4)
139
* @param z - Z component (number/node, optional if x is Vector4)
140
* @param w - W component (number/node, optional if x is Vector4)
141
* @returns Vec4 node
142
*/
143
declare function vec4(
144
x?: NodeRepresentation,
145
y?: NodeRepresentation,
146
z?: NodeRepresentation,
147
w?: NodeRepresentation
148
): Vec4Node;
149
150
/**
151
* Create color node
152
* @param color - Color value (Color, hex number, or RGB components)
153
* @param g - Green component (if color is red component)
154
* @param b - Blue component (if color is red component)
155
* @returns Color node
156
*/
157
declare function color(color: NodeRepresentation, g?: NodeRepresentation, b?: NodeRepresentation): ColorNode;
158
159
/**
160
* Create matrix nodes
161
*/
162
declare function mat3(...values: NodeRepresentation[]): Mat3Node;
163
declare function mat4(...values: NodeRepresentation[]): Mat4Node;
164
```
165
166
**Usage Example:**
167
168
```javascript
169
import { vec3, color, float, uniform } from 'three/tsl';
170
171
// Create vector nodes
172
const position = vec3(0, 1, 0);
173
const direction = vec3(1, 0, 0);
174
const scale = float(2.0);
175
176
// Create uniform inputs
177
const time = uniform(0);
178
const baseColor = uniform(color(0xff0000));
179
const intensity = uniform(1.0);
180
181
// Combine nodes with operations
182
const animatedPosition = position.add(direction.mul(time));
183
const scaledColor = baseColor.mul(intensity);
184
```
185
186
### Mathematical Operations
187
188
Comprehensive mathematical functions and operators for shader computations.
189
190
```javascript { .api }
191
/**
192
* Arithmetic operations
193
*/
194
declare function add(a: NodeRepresentation, b: NodeRepresentation): Node;
195
declare function sub(a: NodeRepresentation, b: NodeRepresentation): Node;
196
declare function mul(a: NodeRepresentation, b: NodeRepresentation): Node;
197
declare function div(a: NodeRepresentation, b: NodeRepresentation): Node;
198
declare function mod(a: NodeRepresentation, b: NodeRepresentation): Node;
199
declare function pow(a: NodeRepresentation, b: NodeRepresentation): Node;
200
201
/**
202
* Trigonometric functions
203
*/
204
declare function sin(node: NodeRepresentation): Node;
205
declare function cos(node: NodeRepresentation): Node;
206
declare function tan(node: NodeRepresentation): Node;
207
declare function asin(node: NodeRepresentation): Node;
208
declare function acos(node: NodeRepresentation): Node;
209
declare function atan(node: NodeRepresentation): Node;
210
declare function atan2(y: NodeRepresentation, x: NodeRepresentation): Node;
211
212
/**
213
* Exponential and logarithmic functions
214
*/
215
declare function exp(node: NodeRepresentation): Node;
216
declare function exp2(node: NodeRepresentation): Node;
217
declare function log(node: NodeRepresentation): Node;
218
declare function log2(node: NodeRepresentation): Node;
219
declare function sqrt(node: NodeRepresentation): Node;
220
declare function inversesqrt(node: NodeRepresentation): Node;
221
222
/**
223
* Common mathematical functions
224
*/
225
declare function abs(node: NodeRepresentation): Node;
226
declare function sign(node: NodeRepresentation): Node;
227
declare function floor(node: NodeRepresentation): Node;
228
declare function ceil(node: NodeRepresentation): Node;
229
declare function fract(node: NodeRepresentation): Node;
230
declare function min(a: NodeRepresentation, b: NodeRepresentation): Node;
231
declare function max(a: NodeRepresentation, b: NodeRepresentation): Node;
232
declare function clamp(value: NodeRepresentation, min: NodeRepresentation, max: NodeRepresentation): Node;
233
declare function mix(a: NodeRepresentation, b: NodeRepresentation, t: NodeRepresentation): Node;
234
declare function step(edge: NodeRepresentation, value: NodeRepresentation): Node;
235
declare function smoothstep(edge0: NodeRepresentation, edge1: NodeRepresentation, value: NodeRepresentation): Node;
236
237
/**
238
* Vector operations
239
*/
240
declare function length(node: NodeRepresentation): Node;
241
declare function distance(a: NodeRepresentation, b: NodeRepresentation): Node;
242
declare function dot(a: NodeRepresentation, b: NodeRepresentation): Node;
243
declare function cross(a: NodeRepresentation, b: NodeRepresentation): Node;
244
declare function normalize(node: NodeRepresentation): Node;
245
declare function reflect(incident: NodeRepresentation, normal: NodeRepresentation): Node;
246
declare function refract(incident: NodeRepresentation, normal: NodeRepresentation, eta: NodeRepresentation): Node;
247
248
/**
249
* Matrix operations
250
*/
251
declare function matrixMultiply(a: NodeRepresentation, b: NodeRepresentation): Node;
252
declare function transpose(matrix: NodeRepresentation): Node;
253
declare function determinant(matrix: NodeRepresentation): Node;
254
declare function inverse(matrix: NodeRepresentation): Node;
255
```
256
257
**Usage Example:**
258
259
```javascript
260
import { vec3, float, sin, cos, normalize, dot, mix, smoothstep, time } from 'three/tsl';
261
262
// Create animated wave effect
263
const position = attribute('position');
264
const waveFreq = float(2.0);
265
const waveAmp = float(0.5);
266
267
const wave = sin(position.y.mul(waveFreq).add(time)).mul(waveAmp);
268
const animatedPosition = position.add(vec3(wave, 0, 0));
269
270
// Create lighting calculation
271
const normal = attribute('normal');
272
const lightDir = normalize(vec3(1, 1, 1));
273
const lightIntensity = max(dot(normal, lightDir), 0);
274
275
// Create color mixing
276
const baseColor = color(0x3366ff);
277
const highlightColor = color(0xffffff);
278
const finalColor = mix(baseColor, highlightColor, lightIntensity);
279
```
280
281
### Texture Operations
282
283
Comprehensive texture sampling and manipulation functions for material creation.
284
285
```javascript { .api }
286
/**
287
* Create texture sampling node
288
* @param texture - Texture uniform or object
289
* @param uv - UV coordinates (vec2 node)
290
* @param bias - Mipmap bias (optional)
291
* @returns Texture sample node
292
*/
293
declare function texture(texture: NodeRepresentation, uv?: NodeRepresentation, bias?: NodeRepresentation): TextureNode;
294
295
/**
296
* Create cube texture sampling node
297
* @param texture - Cube texture uniform
298
* @param direction - Sample direction (vec3 node)
299
* @param bias - Mipmap bias (optional)
300
* @returns Cube texture sample node
301
*/
302
declare function cubeTexture(texture: NodeRepresentation, direction: NodeRepresentation, bias?: NodeRepresentation): CubeTextureNode;
303
304
/**
305
* Texture derivative functions
306
*/
307
declare function textureGrad(
308
texture: NodeRepresentation,
309
uv: NodeRepresentation,
310
dPdx: NodeRepresentation,
311
dPdy: NodeRepresentation
312
): Node;
313
314
declare function textureLod(texture: NodeRepresentation, uv: NodeRepresentation, lod: NodeRepresentation): Node;
315
316
/**
317
* Derivative functions for texture sampling
318
*/
319
declare function dFdx(node: NodeRepresentation): Node;
320
declare function dFdy(node: NodeRepresentation): Node;
321
declare function fwidth(node: NodeRepresentation): Node;
322
323
/**
324
* Texture information functions
325
*/
326
declare function textureSize(texture: NodeRepresentation, lod?: NodeRepresentation): Node;
327
declare function textureQueryLod(texture: NodeRepresentation, uv: NodeRepresentation): Node;
328
```
329
330
**Usage Example:**
331
332
```javascript
333
import { texture, vec2, mul, add, sin, cos, time } from 'three/tsl';
334
335
// Basic texture sampling
336
const diffuseMap = uniform(myTexture);
337
const uv = attribute('uv');
338
const diffuseColor = texture(diffuseMap, uv);
339
340
// Animated texture coordinates
341
const scrollSpeed = float(0.1);
342
const animatedUV = uv.add(vec2(time.mul(scrollSpeed), 0));
343
const scrollingTexture = texture(diffuseMap, animatedUV);
344
345
// Distorted texture sampling
346
const distortion = sin(uv.y.mul(10).add(time)).mul(0.02);
347
const distortedUV = uv.add(vec2(distortion, 0));
348
const distortedTexture = texture(diffuseMap, distortedUV);
349
350
// Multi-texture blending
351
const normalMap = uniform(myNormalTexture);
352
const roughnessMap = uniform(myRoughnessTexture);
353
354
const albedo = texture(diffuseMap, uv);
355
const normal = texture(normalMap, uv);
356
const roughness = texture(roughnessMap, uv).r; // Red channel only
357
```
358
359
### Control Flow and Logic
360
361
Conditional operations and control flow constructs for complex shader logic.
362
363
```javascript { .api }
364
/**
365
* Conditional node for branching logic
366
* @param condition - Boolean condition node
367
* @param ifTrue - Node to use when condition is true
368
* @param ifFalse - Node to use when condition is false
369
* @returns Conditional result node
370
*/
371
declare function cond(condition: NodeRepresentation, ifTrue: NodeRepresentation, ifFalse: NodeRepresentation): Node;
372
373
/**
374
* Logical operations
375
*/
376
declare function and(a: NodeRepresentation, b: NodeRepresentation): Node;
377
declare function or(a: NodeRepresentation, b: NodeRepresentation): Node;
378
declare function not(node: NodeRepresentation): Node;
379
declare function xor(a: NodeRepresentation, b: NodeRepresentation): Node;
380
381
/**
382
* Comparison operations
383
*/
384
declare function equal(a: NodeRepresentation, b: NodeRepresentation): Node;
385
declare function notEqual(a: NodeRepresentation, b: NodeRepresentation): Node;
386
declare function lessThan(a: NodeRepresentation, b: NodeRepresentation): Node;
387
declare function lessThanEqual(a: NodeRepresentation, b: NodeRepresentation): Node;
388
declare function greaterThan(a: NodeRepresentation, b: NodeRepresentation): Node;
389
declare function greaterThanEqual(a: NodeRepresentation, b: NodeRepresentation): Node;
390
391
/**
392
* Select operation (GPU-friendly conditional)
393
* @param condition - Boolean condition
394
* @param a - Value when condition is true
395
* @param b - Value when condition is false
396
* @returns Selected value
397
*/
398
declare function select(condition: NodeRepresentation, a: NodeRepresentation, b: NodeRepresentation): Node;
399
```
400
401
**Usage Example:**
402
403
```javascript
404
import { cond, greaterThan, lessThan, mix, float, color } from 'three/tsl';
405
406
// Conditional color based on height
407
const position = attribute('position');
408
const heightThreshold = float(2.0);
409
const lowColor = color(0x00ff00); // Green
410
const highColor = color(0xff0000); // Red
411
412
const finalColor = cond(
413
greaterThan(position.y, heightThreshold),
414
highColor,
415
lowColor
416
);
417
418
// Multi-level conditional
419
const midThreshold = float(1.0);
420
const midColor = color(0xffff00); // Yellow
421
422
const triColor = cond(
423
greaterThan(position.y, heightThreshold),
424
highColor,
425
cond(
426
greaterThan(position.y, midThreshold),
427
midColor,
428
lowColor
429
)
430
);
431
```
432
433
### Built-in Variables and Constants
434
435
Access to standard shader variables and mathematical constants.
436
437
```javascript { .api }
438
/**
439
* Vertex shader built-ins
440
*/
441
declare const positionLocal: AttributeNode; // Local position
442
declare const positionWorld: Node; // World position
443
declare const positionView: Node; // View space position
444
declare const positionClip: Node; // Clip space position
445
declare const normalLocal: AttributeNode; // Local normal
446
declare const normalWorld: Node; // World normal
447
declare const normalView: Node; // View space normal
448
declare const uv: AttributeNode; // UV coordinates
449
declare const color: AttributeNode; // Vertex colors
450
451
/**
452
* Fragment shader built-ins
453
*/
454
declare const fragCoord: Node; // Fragment coordinates
455
declare const frontFacing: Node; // Whether fragment is front-facing
456
declare const pointCoord: Node; // Point sprite coordinates
457
458
/**
459
* Camera and view uniforms
460
*/
461
declare const cameraPosition: UniformNode; // World camera position
462
declare const cameraViewMatrix: UniformNode; // View matrix
463
declare const cameraProjectionMatrix: UniformNode; // Projection matrix
464
declare const cameraNear: UniformNode; // Near clipping plane
465
declare const cameraFar: UniformNode; // Far clipping plane
466
467
/**
468
* Object transform uniforms
469
*/
470
declare const modelMatrix: UniformNode; // Model matrix
471
declare const modelViewMatrix: UniformNode; // Model-view matrix
472
declare const normalMatrix: UniformNode; // Normal transformation matrix
473
474
/**
475
* Time and animation
476
*/
477
declare const time: UniformNode; // Global time in seconds
478
declare const deltaTime: UniformNode; // Frame delta time
479
480
/**
481
* Mathematical constants
482
*/
483
declare const PI: FloatNode; // π (3.14159...)
484
declare const PI2: FloatNode; // 2π
485
declare const PI_HALF: FloatNode; // π/2
486
declare const RECIPROCAL_PI: FloatNode; // 1/π
487
declare const RECIPROCAL_PI2: FloatNode; // 1/(2π)
488
declare const EPSILON: FloatNode; // Small epsilon value
489
declare const E: FloatNode; // Euler's number (2.718...)
490
```
491
492
### Custom Node Creation
493
494
System for creating reusable custom node functions and effects.
495
496
```javascript { .api }
497
/**
498
* Create custom function node
499
* @param inputs - Input parameter definitions
500
* @param returns - Return type
501
* @param body - Function body as TSL nodes
502
* @returns Custom function node
503
*/
504
declare function tslFn(inputs: { [key: string]: string }, returns: string, body: (inputs: any) => Node): TslFunction;
505
506
/**
507
* Create inline WGSL/GLSL code node
508
* @param code - Raw shader code string
509
* @param inputs - Input nodes array
510
* @returns Code node
511
*/
512
declare function wgsl(code: string, ...inputs: Node[]): CodeNode;
513
declare function glsl(code: string, ...inputs: Node[]): CodeNode;
514
515
/**
516
* Custom node class for complex operations
517
*/
518
abstract class TempNode extends Node {
519
/**
520
* Generate code for this custom node
521
* @param builder - Node builder context
522
* @param output - Output variable name
523
* @returns Generated shader code
524
*/
525
abstract generate(builder: NodeBuilder, output?: string): string;
526
}
527
```
528
529
**Usage Example:**
530
531
```javascript
532
import { tslFn, vec3, float, sin, cos, mul, add } from 'three/tsl';
533
534
// Create custom wave function
535
const wave = tslFn({
536
position: 'vec3',
537
time: 'float',
538
frequency: 'float',
539
amplitude: 'float'
540
}, 'vec3', ({ position, time, frequency, amplitude }) => {
541
const wave = sin(position.y.mul(frequency).add(time)).mul(amplitude);
542
return position.add(vec3(wave, 0, 0));
543
});
544
545
// Use custom function
546
const animatedPosition = wave({
547
position: attribute('position'),
548
time: time,
549
frequency: float(2.0),
550
amplitude: float(0.5)
551
});
552
553
// Create custom material effect
554
const customEffect = tslFn({
555
uv: 'vec2',
556
time: 'float'
557
}, 'vec3', ({ uv, time }) => {
558
const r = sin(uv.x.mul(10).add(time)).mul(0.5).add(0.5);
559
const g = cos(uv.y.mul(10).add(time)).mul(0.5).add(0.5);
560
const b = sin(uv.x.add(uv.y).mul(5).add(time)).mul(0.5).add(0.5);
561
return vec3(r, g, b);
562
});
563
```
564
565
### Material Integration
566
567
Integration with Three.js material system for creating custom shaders with TSL.
568
569
```javascript { .api }
570
/**
571
* Create node material using TSL nodes
572
*/
573
class NodeMaterial extends ShaderMaterial {
574
/**
575
* Create node-based material
576
* @param parameters - Material parameters with TSL nodes
577
*/
578
constructor(parameters?: NodeMaterialParameters);
579
580
/** Whether this is a node material */
581
isNodeMaterial: true;
582
583
/** Vertex position output node */
584
positionNode: Node | null;
585
586
/** Fragment color output node */
587
colorNode: Node | null;
588
589
/** Normal output node */
590
normalNode: Node | null;
591
592
/** Opacity output node */
593
opacityNode: Node | null;
594
595
/** Emissive color node */
596
emissiveNode: Node | null;
597
598
/** Metalness node */
599
metalnessNode: Node | null;
600
601
/** Roughness node */
602
roughnessNode: Node | null;
603
604
/** Custom vertex shader nodes */
605
vertexNode: Node | null;
606
607
/** Custom fragment shader nodes */
608
fragmentNode: Node | null;
609
}
610
611
interface NodeMaterialParameters extends MaterialParameters {
612
colorNode?: Node;
613
opacityNode?: Node;
614
normalNode?: Node;
615
emissiveNode?: Node;
616
metalnessNode?: Node;
617
roughnessNode?: Node;
618
positionNode?: Node;
619
vertexNode?: Node;
620
fragmentNode?: Node;
621
}
622
```
623
624
## Types
625
626
```javascript { .api }
627
// TSL type system
628
type NodeRepresentation = Node | number | boolean | string | Vector2 | Vector3 | Vector4 | Color | Matrix3 | Matrix4;
629
630
// Node builder context
631
interface NodeBuilder {
632
material: Material;
633
renderer: Renderer;
634
object: Object3D;
635
camera: Camera;
636
scene: Scene;
637
638
getUniformFromNode(node: Node): string;
639
getVaryingFromNode(node: Node): string;
640
getAttributeFromNode(node: Node): string;
641
getCode(): string;
642
addFlowCode(code: string): void;
643
}
644
645
// Node frame context
646
interface NodeFrame {
647
time: number;
648
deltaTime: number;
649
frameId: number;
650
renderId: number;
651
652
updateBeforeRender(renderer: Renderer, scene: Scene, camera: Camera, geometry: BufferGeometry, material: Material, object: Object3D): void;
653
}
654
655
// Core node types
656
interface FloatNode extends Node { type: 'float'; }
657
interface IntNode extends Node { type: 'int'; }
658
interface BoolNode extends Node { type: 'bool'; }
659
interface Vec2Node extends Node { type: 'vec2'; }
660
interface Vec3Node extends Node { type: 'vec3'; }
661
interface Vec4Node extends Node { type: 'vec4'; }
662
interface ColorNode extends Node { type: 'vec3'; }
663
interface Mat3Node extends Node { type: 'mat3'; }
664
interface Mat4Node extends Node { type: 'mat4'; }
665
interface TextureNode extends Node { type: 'vec4'; }
666
interface UniformNode extends Node { }
667
interface AttributeNode extends Node { }
668
interface VaryingNode extends Node { }
669
interface CodeNode extends Node { }
670
```
671
672
## Usage Examples
673
674
**Complete Custom Material with TSL:**
675
676
```javascript
677
import * as THREE from 'three';
678
import {
679
NodeMaterial,
680
vec3, vec4, float, color,
681
texture, mix, sin, cos, normalize, dot,
682
time, uv, normalWorld, cameraPosition,
683
uniform, mul, add, pow, clamp
684
} from 'three/tsl';
685
686
// Create custom animated material
687
class AnimatedCrystalMaterial extends NodeMaterial {
688
constructor() {
689
super();
690
691
// Material properties
692
this.baseColor = uniform(color(0x3366ff));
693
this.emissionColor = uniform(color(0x66ccff));
694
this.roughness = uniform(0.1);
695
this.metalness = uniform(0.9);
696
697
// Animation parameters
698
this.animSpeed = uniform(1.0);
699
this.waveFreq = uniform(2.0);
700
this.waveAmp = uniform(0.1);
701
702
this.setupNodes();
703
}
704
705
setupNodes() {
706
// Animated vertex displacement
707
const position = positionLocal;
708
const displacement = sin(position.y.mul(this.waveFreq).add(time.mul(this.animSpeed)))
709
.mul(this.waveAmp);
710
711
this.positionNode = position.add(normalLocal.mul(displacement));
712
713
// Animated colors based on viewing angle
714
const viewDirection = normalize(cameraPosition.sub(positionWorld));
715
const fresnel = dot(normalWorld, viewDirection);
716
const fresnelPow = pow(clamp(fresnel, 0, 1), 2);
717
718
// Animated emission
719
const timeOscillation = sin(time.mul(2)).mul(0.3).add(0.7);
720
const animatedEmission = this.emissionColor.mul(timeOscillation).mul(fresnelPow);
721
722
// Final material properties
723
this.colorNode = this.baseColor;
724
this.emissiveNode = animatedEmission;
725
this.roughnessNode = this.roughness;
726
this.metalnessNode = this.metalness;
727
728
// Custom fragment effects
729
const sparkle = sin(uv.x.mul(50).add(time)).mul(sin(uv.y.mul(50).add(time)));
730
const sparkleIntensity = clamp(sparkle.mul(10), 0, 1);
731
732
this.colorNode = mix(
733
this.baseColor,
734
color(1, 1, 1),
735
sparkleIntensity.mul(0.3)
736
);
737
}
738
739
// Update animation parameters
740
updateAnimation(deltaTime) {
741
// Animation updates can be done here
742
// Properties are automatically updated via uniforms
743
}
744
}
745
746
// Usage in scene
747
const geometry = new THREE.IcosahedronGeometry(1, 2);
748
const material = new AnimatedCrystalMaterial();
749
const crystal = new THREE.Mesh(geometry, material);
750
751
scene.add(crystal);
752
753
// Animation loop
754
const clock = new THREE.Clock();
755
function animate() {
756
const deltaTime = clock.getDelta();
757
material.updateAnimation(deltaTime);
758
759
requestAnimationFrame(animate);
760
renderer.render(scene, camera);
761
}
762
animate();
763
```