Skip to content
45 changes: 34 additions & 11 deletions examples-testing/changes.patch
Original file line number Diff line number Diff line change
Expand Up @@ -14872,7 +14872,7 @@ index 43d162ab5..259faad4c 100644
const posY = instanceIndex.div(width);
const indexUV = uvec2(posX, posY);
diff --git a/examples-testing/examples/webgpu_compute_texture_3d.ts b/examples-testing/examples/webgpu_compute_texture_3d.ts
index ccdfba0be..e738cd82a 100644
index ccdfba0be..4e0661c5d 100644
--- a/examples-testing/examples/webgpu_compute_texture_3d.ts
+++ b/examples-testing/examples/webgpu_compute_texture_3d.ts
@@ -23,9 +23,9 @@ import { Inspector } from 'three/addons/inspector/Inspector.js';
Expand Down Expand Up @@ -14919,10 +14919,10 @@ index ccdfba0be..e738cd82a 100644
+ steps = float(100),
+ }: {
+ texture: THREE.Texture3DNode;
+ range?: THREE.InputNode<'float', number>;
+ threshold?: THREE.InputNode<'float', number>;
+ opacity?: THREE.InputNode<'float', number>;
+ steps?: THREE.InputNode<'float', number>;
+ range?: THREE.Node<'float'>;
+ threshold?: THREE.Node<'float'>;
+ opacity?: THREE.Node<'float'>;
+ steps?: THREE.Node<'float'>;
+ }) => {
const finalColor = vec4(0).toVar();

Expand Down Expand Up @@ -15066,7 +15066,7 @@ index 6fbdb55ae..fd5ec5705 100644
init();

diff --git a/examples-testing/examples/webgpu_custom_fog.ts b/examples-testing/examples/webgpu_custom_fog.ts
index fcae79b96..0ce427a37 100644
index fcae79b96..be07fc038 100644
--- a/examples-testing/examples/webgpu_custom_fog.ts
+++ b/examples-testing/examples/webgpu_custom_fog.ts
@@ -4,8 +4,8 @@ import { color, fog, float, positionWorld, triNoise3D, positionView, normalWorld
Expand All @@ -15080,6 +15080,29 @@ index fcae79b96..0ce427a37 100644

init();

@@ -17,8 +17,11 @@ function init() {

// custom fog

- const skyColor = color(0xf0f5f5);
- const groundColor = color(0xd0dee7);
+ const skyColorValue = 0xf0f5f5;
+ const groundColorValue = 0xd0dee7;
+
+ const skyColor = color(skyColorValue);
+ const groundColor = color(groundColorValue);

const fogNoiseDistance = positionView.z.negate().smoothstep(0, camera.far - 300);

@@ -79,7 +82,7 @@ function init() {

// lights

- scene.add(new THREE.HemisphereLight(skyColor.value, groundColor.value, 0.5));
+ scene.add(new THREE.HemisphereLight(skyColorValue, groundColorValue, 0.5));

// geometry

diff --git a/examples-testing/examples/webgpu_custom_fog_background.ts b/examples-testing/examples/webgpu_custom_fog_background.ts
index a9b619345..e482a1e2e 100644
--- a/examples-testing/examples/webgpu_custom_fog_background.ts
Expand Down Expand Up @@ -21378,7 +21401,7 @@ index 0c85390dd..23cd2ae09 100644

let density = sampleGrain(1);
diff --git a/examples-testing/examples/webgpu_volume_cloud.ts b/examples-testing/examples/webgpu_volume_cloud.ts
index 1d46c3543..e4d6147fe 100644
index 1d46c3543..5f4fdfa36 100644
--- a/examples-testing/examples/webgpu_volume_cloud.ts
+++ b/examples-testing/examples/webgpu_volume_cloud.ts
@@ -8,8 +8,8 @@ import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js';
Expand Down Expand Up @@ -21414,10 +21437,10 @@ index 1d46c3543..e4d6147fe 100644
+ steps = float(100),
+ }: {
+ texture: THREE.TextureNode;
+ range: THREE.InputNode<'float', number>;
+ threshold: THREE.InputNode<'float', number>;
+ opacity: THREE.InputNode<'float', number>;
+ steps: THREE.InputNode<'float', number>;
+ range: THREE.Node<'float'>;
+ threshold: THREE.Node<'float'>;
+ opacity: THREE.Node<'float'>;
+ steps: THREE.Node<'float'>;
+ }) => {
const finalColor = vec4(0).toVar();

Expand Down
12 changes: 7 additions & 5 deletions jsdoc-testing/changes.patch
Original file line number Diff line number Diff line change
Expand Up @@ -11029,10 +11029,10 @@ index b5f1a2917..49b3c2132 100644
+
+export default StructTypeNode;
diff --git a/jsdoc-testing/jsdoc/nodes/core/UniformNode.d.ts b/jsdoc-testing/jsdoc/nodes/core/UniformNode.d.ts
index f4cb493fb..9778fefac 100644
index f4cb493fb..8b312e70c 100644
--- a/jsdoc-testing/jsdoc/nodes/core/UniformNode.d.ts
+++ b/jsdoc-testing/jsdoc/nodes/core/UniformNode.d.ts
@@ -1,11 +1,22 @@
@@ -1,11 +1,23 @@
-export default UniformNode;
-export function uniform(value: any | string, type?: string): UniformNode;
+import InputNode from './InputNode.js';
Expand All @@ -11047,6 +11047,7 @@ index f4cb493fb..9778fefac 100644
+import { Matrix3 } from '../../math/Matrix3.js';
+import { Matrix4 } from '../../math/Matrix4.js';
+import { Color } from '../../math/Color.js';
+import VarNode from './VarNode.js';
+
/**
* Class for representing a uniform.
Expand All @@ -11058,7 +11059,7 @@ index f4cb493fb..9778fefac 100644
/**
* This flag can be used for type testing.
*
@@ -28,7 +39,7 @@ declare class UniformNode extends InputNode {
@@ -28,7 +40,7 @@ declare class UniformNode extends InputNode {
* @param {string} name - The name of the uniform.
* @return {UniformNode} A reference to this node.
*/
Expand All @@ -11067,7 +11068,7 @@ index f4cb493fb..9778fefac 100644
/**
* Sets the {@link UniformNode#name} property.
*
@@ -36,14 +47,14 @@ declare class UniformNode extends InputNode {
@@ -36,14 +48,14 @@ declare class UniformNode extends InputNode {
* @param {string} name - The name of the uniform.
* @return {UniformNode} A reference to this node.
*/
Expand All @@ -11084,7 +11085,7 @@ index f4cb493fb..9778fefac 100644
/**
* Returns the {@link UniformNode#groupNode}.
*
@@ -58,8 +69,44 @@ declare class UniformNode extends InputNode {
@@ -58,8 +70,45 @@ declare class UniformNode extends InputNode {
* @return {string} The uniform hash.
*/
getUniformHash(builder: NodeBuilder): string;
Expand Down Expand Up @@ -11122,6 +11123,7 @@ index f4cb493fb..9778fefac 100644
+ (value: Matrix4): UniformNode<"mat4", Matrix4>;
+ (value: Color): UniformNode<"color", Color>;
+ <TNodeType, TValue>(value: InputNode<TNodeType, TValue>): UniformNode<TNodeType, TValue>;
+ <TNodeType, TValue>(value: VarNode<TNodeType, InputNode<TNodeType, TValue>>): UniformNode<TNodeType, TValue>;
+}
+
+/**
Expand Down
148 changes: 147 additions & 1 deletion tsl-testing/TSLCore.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect, test } from 'vitest';
import { nodeObject, vec3 } from 'three/tsl';
import { bool, color, float, int, ivec2, mat2, mat3, mat4, nodeObject, uint, vec2, vec3, vec4 } from 'three/tsl';
import * as THREE from 'three/webgpu';

const renderer = new THREE.WebGPURenderer();
Expand Down Expand Up @@ -82,3 +82,149 @@ test('nodeObject(object)', () => {
const result: typeof randomObject = nodeObject(randomObject);
expect(result).toStrictEqual(randomObject);
});

function assertConstructorNode<TNodeType>(
node: THREE.VarNode<TNodeType, THREE.ConstNode<TNodeType, unknown>>,
nodeType: string,
valueClass?: unknown,
) {
expect(node).toBeInstanceOf(THREE.VarNode);
expect(node.getNodeType(nodeBuilder)).toBe(nodeType);
expect(node.node).toBeInstanceOf(THREE.ConstNode);
expect(node.node.getNodeType(nodeBuilder)).toBe(nodeType);
if (valueClass) expect(node.node.value).toBeInstanceOf(valueClass);
}

test('color', () => {
let node: THREE.VarNode<'color', THREE.ConstNode<'color', THREE.Color>> = color();
assertConstructorNode(node, 'color', THREE.Color);

node = color('red');
assertConstructorNode(node, 'color', THREE.Color);

node = color(0xff0000);
assertConstructorNode(node, 'color', THREE.Color);

node = color(new THREE.Color());
assertConstructorNode(node, 'color', THREE.Color);

node = color(0, 100, 255);
assertConstructorNode(node, 'color', THREE.Color);
});

test('float', () => {
let node: THREE.VarNode<'float', THREE.ConstNode<'float', number>> = float();
assertConstructorNode(node, 'float');
expect(node.node.value).toBeTypeOf('number');

node = float(5);
assertConstructorNode(node, 'float');
expect(node.node.value).toBeTypeOf('number');
});

test('int', () => {
let node: THREE.VarNode<'int', THREE.ConstNode<'int', number>> = int();
assertConstructorNode(node, 'int');
expect(node.node.value).toBeTypeOf('number');

node = int(5);
assertConstructorNode(node, 'int');
expect(node.node.value).toBeTypeOf('number');
});

test('uint', () => {
let node: THREE.VarNode<'uint', THREE.ConstNode<'uint', number>> = uint();
assertConstructorNode(node, 'uint');
expect(node.node.value).toBeTypeOf('number');

node = uint(5);
assertConstructorNode(node, 'uint');
expect(node.node.value).toBeTypeOf('number');
});

test('bool', () => {
let node: THREE.VarNode<'bool', THREE.ConstNode<'bool', boolean>> = bool();
assertConstructorNode(node, 'bool');
expect(node.node.value).toBeTypeOf('boolean');

node = bool(true);
assertConstructorNode(node, 'bool');
expect(node.node.value).toBeTypeOf('boolean');
});

test('vec2', () => {
let node: THREE.VarNode<'vec2', THREE.ConstNode<'vec2', THREE.Vector2>> = vec2();
assertConstructorNode(node, 'vec2', THREE.Vector2);

node = vec2(1);
assertConstructorNode(node, 'vec2', THREE.Vector2);

node = vec2(1, 2);
assertConstructorNode(node, 'vec2', THREE.Vector2);

node = vec2(new THREE.Vector2());
assertConstructorNode(node, 'vec2', THREE.Vector2);
});

test('ivec2', () => {
let node: THREE.VarNode<'ivec2', THREE.ConstNode<'ivec2', THREE.Vector2>> = ivec2(1, 2);
assertConstructorNode(node, 'ivec2', THREE.Vector2);
});

test('vec3', () => {
let node: THREE.VarNode<'vec3', THREE.ConstNode<'vec3', THREE.Vector3>> = vec3();
assertConstructorNode(node, 'vec3', THREE.Vector3);

node = vec3(1);
assertConstructorNode(node, 'vec3', THREE.Vector3);

node = vec3(1, 2);
assertConstructorNode(node, 'vec3', THREE.Vector3);

node = vec3(1, 2, 3);
assertConstructorNode(node, 'vec3', THREE.Vector3);

node = vec3(new THREE.Vector3());
assertConstructorNode(node, 'vec3', THREE.Vector3);
});

test('vec4', () => {
let node: THREE.VarNode<'vec4', THREE.ConstNode<'vec4', THREE.Vector4>> = vec4();
assertConstructorNode(node, 'vec4', THREE.Vector4);

node = vec4(1);
assertConstructorNode(node, 'vec4', THREE.Vector4);

node = vec4(1, 2);
assertConstructorNode(node, 'vec4', THREE.Vector4);

node = vec4(1, 2, 3);
assertConstructorNode(node, 'vec4', THREE.Vector4);

node = vec4(1, 2, 3, 4);
assertConstructorNode(node, 'vec4', THREE.Vector4);

node = vec4(new THREE.Vector4());
assertConstructorNode(node, 'vec4', THREE.Vector4);
});

test('mat2', () => {
let node: THREE.VarNode<'mat2', THREE.ConstNode<'mat2', THREE.Matrix2>> = mat2(new THREE.Matrix2());
assertConstructorNode(node, 'mat2', THREE.Matrix2);
});

test('mat3', () => {
let node: THREE.VarNode<'mat3', THREE.ConstNode<'mat3', THREE.Matrix3>> = mat3(new THREE.Matrix3());
assertConstructorNode(node, 'mat3', THREE.Matrix3);

node = mat3();
assertConstructorNode(node, 'mat3', THREE.Matrix3);
});

test('mat4', () => {
let node: THREE.VarNode<'mat4', THREE.ConstNode<'mat4', THREE.Matrix4>> = mat4(new THREE.Matrix4());
assertConstructorNode(node, 'mat4', THREE.Matrix4);

node = mat4();
assertConstructorNode(node, 'mat4', THREE.Matrix4);
});
2 changes: 1 addition & 1 deletion types/three/src/math/ColorManagement.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export interface ColorManagement {

getTransfer: (colorSpace: string) => ColorSpaceTransfer;

getLuminanceCoefficients: (target: Vector3, colorSpace?: string) => [number, number, number];
getLuminanceCoefficients: (target: Vector3, colorSpace?: string) => Vector3;

define: (colorSpaces: Record<string, ColorSpaceDefinition>) => void;

Expand Down
2 changes: 2 additions & 0 deletions types/three/src/nodes/core/UniformNode.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import InputNode from "./InputNode.js";
import NodeBuilder from "./NodeBuilder.js";
import NodeFrame from "./NodeFrame.js";
import UniformGroupNode from "./UniformGroupNode.js";
import VarNode from "./VarNode.js";

/**
* Class for representing a uniform.
Expand Down Expand Up @@ -99,6 +100,7 @@ interface Uniform {
(value: Matrix4): UniformNode<"mat4", Matrix4>;
(value: Color): UniformNode<"color", Color>;
<TNodeType, TValue>(value: InputNode<TNodeType, TValue>): UniformNode<TNodeType, TValue>;
<TNodeType, TValue>(value: VarNode<TNodeType, InputNode<TNodeType, TValue>>): UniformNode<TNodeType, TValue>;
}

/**
Expand Down
26 changes: 16 additions & 10 deletions types/three/src/nodes/core/VarNode.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Node from "./Node.js";

interface VarNodeInterface {
node: Node;
interface VarNodeInterface<TNode> {
node: TNode;
name: string | null;

readonly isVarNode: true;
Expand All @@ -15,25 +15,31 @@ interface VarNodeInterface {
}

declare const VarNode: {
new<TNodeType>(node: Node<TNodeType>, name?: string | null, readOnly?: boolean): VarNode<TNodeType>;
new<TNodeType, TNode>(node: TNode, name?: string | null, readOnly?: boolean): VarNode<TNodeType, TNode>;
};

type VarNode<TNodeType = unknown> = Node<TNodeType> & VarNodeInterface;
type VarNode<TNodeType, TNode> = Node<TNodeType> & VarNodeInterface<TNode>;

export default VarNode;

export const Var: <TNodeType>(node: Node<TNodeType>, name?: string | null) => VarNode<TNodeType>;
export const Var: <TNodeType, TNode extends Node<TNodeType>>(
node: TNode,
name?: string | null,
) => VarNode<TNodeType, TNode>;

export const Const: <TNodeType>(node: Node<TNodeType>, name?: string | null) => VarNode<TNodeType>;
export const Const: <TNodeType, TNode extends Node<TNodeType>>(
node: TNode,
name?: string | null,
) => VarNode<TNodeType, TNode>;

export const VarIntent: <TNodeType>(node: Node<TNodeType>) => Node<TNodeType>;
export const VarIntent: <TNodeType, TNode extends Node<TNodeType>>(node: TNode) => VarNode<TNodeType, TNode>;

declare module "./Node.js" {
interface NodeExtensions<TNodeType> {
toVar: (name?: string | null) => VarNode<TNodeType>;
toVar: (name?: string | null) => VarNode<TNodeType, this>;

toConst: (name?: string | null) => VarNode<TNodeType>;
toConst: (name?: string | null) => VarNode<TNodeType, this>;

toVarIntent: () => Node<TNodeType>;
toVarIntent: () => VarNode<TNodeType, this>;
}
}
4 changes: 2 additions & 2 deletions types/three/src/nodes/functions/ShadowMaskModel.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import LightingModel from "../core/LightingModel.js";
import VarNode from "../core/VarNode.js";
import Node from "../core/Node.js";

export default class ShadowMaskModel extends LightingModel {
shadowNode: VarNode;
shadowNode: Node;

constructor();
}
Loading