From 6879228936be0db8301e012dad6784b3108ee496 Mon Sep 17 00:00:00 2001 From: Cody Bennett Date: Wed, 26 Feb 2025 12:12:10 -0600 Subject: [PATCH 1/2] fix(shaderMaterial): infer uniforms types --- src/core/shaderMaterial.tsx | 91 ++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 51 deletions(-) diff --git a/src/core/shaderMaterial.tsx b/src/core/shaderMaterial.tsx index f4ab973d9..cfcd4b49a 100644 --- a/src/core/shaderMaterial.tsx +++ b/src/core/shaderMaterial.tsx @@ -1,60 +1,49 @@ import * as THREE from 'three' -import { MeshBVHUniformStruct } from 'three-mesh-bvh' +import { type ConstructorRepresentation } from '@react-three/fiber' +import { type MeshBVHUniformStruct } from 'three-mesh-bvh' -export function shaderMaterial( - uniforms: { - [name: string]: - | THREE.CubeTexture - | THREE.Texture - | Int32Array - | Float32Array - | THREE.Matrix4 - | THREE.Matrix3 - | THREE.Quaternion - | THREE.Vector4 - | THREE.Vector3 - | THREE.Vector2 - | THREE.Color - | MeshBVHUniformStruct - | number - | boolean - | Array - | null - }, +type UniformValue = + | THREE.Texture + | THREE.TypedArray + | THREE.Matrix4 + | THREE.Matrix3 + | THREE.Quaternion + | THREE.Vector4 + | THREE.Vector3 + | THREE.Vector2 + | THREE.Color + | MeshBVHUniformStruct // TODO: remove? + | number + | boolean + | null + +type Uniforms = Record | Array> + +export function shaderMaterial( + uniforms: U, vertexShader: string, fragmentShader: string, - onInit?: (material?: THREE.ShaderMaterial) => void + onInit?: (material?: M) => void ) { - const material = class extends THREE.ShaderMaterial { - public key: string = '' - constructor(parameters = {}) { - const entries = Object.entries(uniforms) - // Create unforms and shaders - super({ - uniforms: entries.reduce((acc, [name, value]) => { - const uniform = THREE.UniformsUtils.clone({ [name]: { value } }) - return { - ...acc, - ...uniform, - } - }, {}), - vertexShader, - fragmentShader, - }) - // Create getter/setters - entries.forEach(([name]) => - Object.defineProperty(this, name, { - get: () => this.uniforms[name].value, - set: (v) => (this.uniforms[name].value = v), + return class extends THREE.ShaderMaterial { + key = THREE.MathUtils.generateUUID() + + constructor(parameters?: THREE.ShaderMaterialParameters) { + super({ vertexShader, fragmentShader, ...parameters }) + + for (const key in uniforms) { + this.uniforms[key] = new THREE.Uniform(uniforms[key]) + Object.defineProperty(this, key, { + get() { + return this.uniforms[key].value + }, + set(value) { + this.uniforms[key].value = value + }, }) - ) + } - // Assign parameters, this might include uniforms - Object.assign(this, parameters) - // Call onInit - if (onInit) onInit(this) + onInit?.(this as unknown as M) } - } as unknown as typeof THREE.ShaderMaterial & { key: string } - material.key = THREE.MathUtils.generateUUID() - return material + } as unknown as ConstructorRepresentation } From 7e5c7f0643cf66aa394f3b0867991e671d764588 Mon Sep 17 00:00:00 2001 From: Cody Bennett Date: Wed, 26 Feb 2025 12:19:01 -0600 Subject: [PATCH 2/2] fix: make shader key static --- src/core/shaderMaterial.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/shaderMaterial.tsx b/src/core/shaderMaterial.tsx index cfcd4b49a..a2ff4c2e9 100644 --- a/src/core/shaderMaterial.tsx +++ b/src/core/shaderMaterial.tsx @@ -19,14 +19,14 @@ type UniformValue = type Uniforms = Record | Array> -export function shaderMaterial( +export function shaderMaterial( uniforms: U, vertexShader: string, fragmentShader: string, onInit?: (material?: M) => void ) { return class extends THREE.ShaderMaterial { - key = THREE.MathUtils.generateUUID() + static key = THREE.MathUtils.generateUUID() constructor(parameters?: THREE.ShaderMaterialParameters) { super({ vertexShader, fragmentShader, ...parameters }) @@ -45,5 +45,5 @@ export function shaderMaterial + } as unknown as ConstructorRepresentation & { key: string } }