y11i-3d-tsl

TSL Implementation Guide

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "y11i-3d-tsl" with this command: npx skills add y11i-3d/tsl/y11i-3d-tsl-y11i-3d-tsl

TSL Implementation Guide

Important: This guide is specifically based on Three.js v0.183.0 . Due to TSL's rapid evolution, even minor version updates may render these patterns and workarounds obsolete.

Core Principle: The Single Source of Truth

TSL (Three.js Shader Language) is in a phase of rapid evolution, where APIs and patterns change frequently. In this environment, the only reliable reference for implementation is the type definitions.

  • Absolute Authority of @types/three :

Treat the local type definitions as the source of truth. When implementing or debugging TSL, do not rely on internal knowledge or external summaries. Inspect node_modules/@types/three directly, tracing signatures and return types to ensure alignment with the current API state.

  • Avoid Internet-Based Research:

Web-found information (blogs, tutorials) is chronically outdated for TSL. Relying on such data is a primary source of syntax errors and must be avoided.

Proactive Use of .toVar()

TSL intermediate nodes (const x = ... ) are operation references that are inlined in the generated shader code unless .toVar() is used. Missing .toVar() in required places causes critical logic errors and performance degradation.

When updating values via .assign() :

Use .toVar() for any variable that needs to be updated (reassigned) or maintain state throughout an algorithm. .assign() cannot be called on nodes that haven't been materialized with .toVar() .

// NG: const count = float(0); count.addAssign(1);

// OK: const count = float(0).toVar(); count.addAssign(1);

When a calculation is referenced two or more times:

Excluding simple literals or swizzles, always use .toVar() to store a result if it is used in multiple places. Failure to do so causes the operation graph to be duplicated and re-executed in the output shader, significantly degrading performance.

// NG: pow() is duplicated in the generated shader const color1 = baseColor1.mul(pow(d, 5.0)); const color2 = baseColor2.mul(pow(d, 5.0));

// OK: Calculated once and reused const intensity = pow(d, 5.0).toVar(); const color1 = baseColor1.mul(intensity); const color2 = baseColor2.mul(intensity);

Use .toVar() to balance between state management and code optimization. If a calculation is referenced only once and requires no updates, omit .toVar() to produce clean, inlined shader code. Otherwise, prioritize .toVar() to prevent logic errors and redundant calculations.

Node Type Definition

Import the Node type from three/webgpu :

import { type Node } from "three/webgpu";

For unions of Node types, use Node<A> | Node<B> instead of Node<A | B> . The latter often triggers compile errors (e.g., by resolving to 'never').

// NG: Fails to compile type FloatOrVector = "float" | "vec2" | "vec3" | "vec4"; Fn(([a, b]: [Node<FloatOrVector>, Node<FloatOrVector>]) => { return a.add(b); // never });

// OK: At least it compiles, though type inference is poor type FloatOrVectorNode = | Node<"float"> | Node<"vec2"> | Node<"vec3"> | Node<"vec4">; Fn(([a, b]: [FloatOrVectorNode, FloatOrVectorNode]) => { return a.add(b); // Node<"vec4"> });

Fn Function Inference

Fn 's default type inference is unreliable and often too loose. Manually define the function signature with as unknown as to enforce strict type safety and prevent loss of specific type information.

Fn(([a, b]: [FloatOrVectorNode, FloatOrVectorNode]) => { return a.add(b); }) as unknown as { <T extends FloatOrVectorNode>(a: T | number, b: T | number): T; (a: number, b: number): Node<"float">; };

Math Function Vector Issues

Important: This is a fallback workaround. Only apply this if you encounter a type error when passing a vector to a function that should support it.

Some mathematical functions are defined to accept only scalar inputs, even though they support vectors in practice. Use as any to bypass the incorrect scalar-only definition and restore the correct Node type.

const v = vec3(1, 4, 9); // eslint-disable-next-line @typescript-eslint/no-explicit-any const res = sqrt(v as any) as unknown as Node<"vec3">;

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Youtube Podcast Generator

Extracts the original text of Youtube video and converts it into a multi-voice AI podcast using a local Node.js API and FFmpeg. It also can show you the text...

Registry SourceRecently Updated
General

ERPClaw

AI-native ERP system with self-extending OS. Full accounting, invoicing, inventory, purchasing, tax, billing, HR, payroll, advanced accounting (ASC 606/842,...

Registry SourceRecently Updated
General

Whisper AI Audio to Text Transcriber

Turn raw transcripts into structured summaries, meeting minutes, and action items.

Registry SourceRecently Updated
General

Task Planner

- **name**: Task Planner. Use when you need task planner capabilities. Triggers on: task planner.

Registry SourceRecently Updated