import { useMemo } from "react" import { RawShaderMaterial, ShaderMaterial, ShaderMaterialParameters } from "three" type IUniform = { value: unknown } type ShaderProgram = {}> = ShaderMaterial & { uniforms: U setDefine: (name: string, value: string) => void } export function useShader = {}>(parameters: Omit, uniforms: U = {} as U): ShaderProgram { const program = useMemo(() => { const p = new ShaderMaterial({ ...parameters, uniforms }) as ShaderProgram p.setDefine = (name, value) => { p.defines[name] = value p.needsUpdate = true } return p }, [parameters.vertexShader, parameters.fragmentShader]) return program } type RawShaderProgram = {}> = RawShaderMaterial & { uniforms: U setDefine: (name: string, value: string) => void } export function useRawShader = {}>(parameters: Omit, uniforms: U = {} as U): RawShaderProgram { const program = useMemo(() => { const p = new RawShaderMaterial({ ...parameters, uniforms }) as RawShaderProgram return p }, [parameters.vertexShader, parameters.fragmentShader]) return program }