or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animation.mdcameras.mdgeometries.mdindex.mdlights.mdloaders.mdmaterials.mdmath.mdrenderers.mdscene-management.mdtsl.mdwebgpu.md

tsl.mddocs/

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

```