The addition of node type generics in r183 is great. But it seems to have many breakages and need refinements, which appear to be already planned in #2049.
The purpose of this issue is to list the concrete issues and feature requests that are blocking me from migrating an existing codebase to r183 types as an example. I could work on most of them, but 2 and 3 would need your assistance because the underlying issues seem to be much broader.
- Chained methods on Node<unknown>
Basic chained methods like toConst(), toVar(), context() and swizzling are absent unless the node has a type other than unknown. This leads to many type breakages.
This is understandable, but given that most advanced nodes (e.g. compute nodes and those in the addon) don't have definite types right now, it would be more reasonable to include these methods on Node<unknown>.
- Function types on vectors
Most math functions should work with vectors component-wise, as well as integer types, but their types only accept float.
pow(vec3(), 1.5) // expected: Node<'vec3'>
sqrt(vec3()) // expected: Node<'vec3'>
fwidth(vec3()) // expected: Node<'vec3'>
greaterThan(vec3(), 0) // expected: Node<'bvec3'>
int(0).negate() // expected: Node<'int'>
ivec2().sign() // expected: Node<'ivec2'>
- Coerced types on arithmetic operations
Arithmetic operations like vec2 * ivec2 and ivec2 * vec2 are allowed at the TSL level, and their types are coerced to vec2 * vec2(ivec2) -> vec2 and ivec2 * ivec2(vec2) -> ivec2 respectively, but these are not supported in the current types and result in type errors instead.
vec2().mul(ivec2()) // expected: Node<'vec2'>
ivec2().mul(vec2()) // expected: Node<'ivec2'>
- Member types on StructNode
StructNode.get() always returns Node, so arithmetic operations require type casting.
It would be ideal to add generics to StructNode and resolve member types accordingly.
const S = struct({
a: 'vec3',
b: 'float'
})
const s = S(vec3(), float())
const a = s.get('a') // expected: Node<'vec3'>, actual: Node
const b = s.get('b') // expected: Node<'float'>, actual: Node
- ivecN, uvecN, bvecN functions with VectorN instances
ivecN, uvecN, and bvecN functions should also accept VectorN instances, just like vecN functions do.
ivec2(new Vector2()) // expected: Node<'ivec2'>
- Generics on compute nodes
Types for most compute shader nodes are missing. This would be largely alleviated if 1 is addressed.
globalId.xy // expected: Node<'ivec2'>
declare const storage: StorageBufferNode<'int'>
atomicAdd(storage.element(0), 1) // expected: Node<'int'>
- Refinement on UniformNode inference
UniformNode now takes two type parameters, but the second one can be trivially inferred from the first.
const node: UniformNode<'vec3'> // UniformNode<'vec3', Vector3>
- Array functions with struct
Array functions like instancedArray and attributeArray can take StructTypeNode. But this would require reworking the type of StorageBufferNode, especially if we will support generics on StructNode mentioned in 4.
const S = struct({ ... })
instancedArray(1, S) // expected: StorageBufferNode<StructNode>
- TextureNode with DepthTexture always samples float
A quick workaround would be to overload PassNode.getTextureNode('depth') to return TextureNode<'float'>, because this is the most common way users access such nodes.
const passNode = pass(scene, camera)
const depthNode = passNode.getTextureNode('depth') // expected: TextureNode<'float'>
The addition of node type generics in r183 is great. But it seems to have many breakages and need refinements, which appear to be already planned in #2049.
The purpose of this issue is to list the concrete issues and feature requests that are blocking me from migrating an existing codebase to r183 types as an example. I could work on most of them, but 2 and 3 would need your assistance because the underlying issues seem to be much broader.
Basic chained methods like
toConst(),toVar(),context()and swizzling are absent unless the node has a type other thanunknown. This leads to many type breakages.This is understandable, but given that most advanced nodes (e.g. compute nodes and those in the addon) don't have definite types right now, it would be more reasonable to include these methods on
Node<unknown>.Most math functions should work with vectors component-wise, as well as integer types, but their types only accept
float.Arithmetic operations like
vec2 * ivec2andivec2 * vec2are allowed at the TSL level, and their types are coerced tovec2 * vec2(ivec2) -> vec2andivec2 * ivec2(vec2) -> ivec2respectively, but these are not supported in the current types and result in type errors instead.StructNode.get()always returnsNode, so arithmetic operations require type casting.It would be ideal to add generics to
StructNodeand resolve member types accordingly.ivecN,uvecN, andbvecNfunctions should also acceptVectorNinstances, just likevecNfunctions do.Types for most compute shader nodes are missing. This would be largely alleviated if 1 is addressed.
UniformNodenow takes two type parameters, but the second one can be trivially inferred from the first.Array functions like
instancedArrayandattributeArraycan takeStructTypeNode. But this would require reworking the type ofStorageBufferNode, especially if we will support generics onStructNodementioned in 4.A quick workaround would be to overload
PassNode.getTextureNode('depth')to returnTextureNode<'float'>, because this is the most common way users access such nodes.