diff --git a/src/index.tsx b/src/index.tsx index 4a5aaee..bb42a51 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -8,7 +8,7 @@ import { MeshLambertMaterialProps, MeshStandardMaterialProps, } from '@react-three/fiber' -import React, { useMemo } from 'react' +import React, { useMemo, useRef, useEffect, useLayoutEffect } from 'react' import mergeRefs from 'react-merge-refs' import { DepthProps, @@ -69,14 +69,14 @@ const LayerMaterial = React.forwardRef< LAYERS.LayerMaterial, React.PropsWithChildren> >(({ children, ...props }, forwardRef) => { - const ref = React.useRef(null!) + const ref = React.useRef(null!) + const [args, otherProps] = useMemo(() => getLayerMaterialArgs(props), [props]) - React.useLayoutEffect(() => { + useLayoutEffect(() => { ref.current.layers = (ref.current as any).__r3f.objects - ref.current.refresh() - }, [children]) - - const [args, otherProps] = useMemo(() => getLayerMaterialArgs(props), [props]) + // This will fire before all children, allow possible children to refresh again + ref.current.__hasRefreshed = false + }) return ( @@ -98,49 +98,63 @@ function getNonUniformArgs(props: any) { ] as any } +let hasRefreshed = false +function useRefresh({ mode, visible, type, mapping, map, axes }: any) { + const ref = useRef() + useEffect(() => { + const parent: LAYERS.LayerMaterial & { __hasRefreshed: boolean } = (ref.current as any)?.__r3f?.parent + // Refresh parent material on mount + if (parent && parent.__hasRefreshed == false) { + parent.refresh() + parent.__hasRefreshed = true + } + }, [mode, visible, type, mapping, map, axes]) + return ref +} + const Depth = React.forwardRef((props, forwardRef) => { - //@ts-ignore - return + const ref = useRefresh(props) + return }) as React.ForwardRefExoticComponent> -const Color = React.forwardRef((props, ref) => { - //@ts-ignore - return +const Color = React.forwardRef((props, forwardRef) => { + const ref = useRefresh(props) + return }) as React.ForwardRefExoticComponent> -const Noise = React.forwardRef((props, ref) => { - //@ts-ignore - return +const Noise = React.forwardRef((props, forwardRef) => { + const ref = useRefresh(props) + return }) as React.ForwardRefExoticComponent> -const Fresnel = React.forwardRef((props, ref) => { - //@ts-ignore - return +const Fresnel = React.forwardRef((props, forwardRef) => { + const ref = useRefresh(props) + return }) as React.ForwardRefExoticComponent> -const Gradient = React.forwardRef((props, ref) => { - //@ts-ignore - return +const Gradient = React.forwardRef((props, forwardRef) => { + const ref = useRefresh(props) + return }) as React.ForwardRefExoticComponent> -const Matcap = React.forwardRef((props, ref) => { - //@ts-ignore - return +const Matcap = React.forwardRef((props, forwardRef) => { + const ref = useRefresh(props) + return }) as React.ForwardRefExoticComponent> -const Texture = React.forwardRef((props, ref) => { - //@ts-ignore - return +const Texture = React.forwardRef((props, forwardRef) => { + const ref = useRefresh(props) + return }) as React.ForwardRefExoticComponent> -const Displace = React.forwardRef((props, ref) => { - //@ts-ignore - return +const Displace = React.forwardRef((props, forwardRef) => { + const ref = useRefresh(props) + return }) as React.ForwardRefExoticComponent> -const Normal = React.forwardRef((props, ref) => { - //@ts-ignore - return +const Normal = React.forwardRef((props, forwardRef) => { + const ref = useRefresh(props) + return }) as React.ForwardRefExoticComponent> export { DebugLayerMaterial, LayerMaterial, Depth, Color, Noise, Fresnel, Gradient, Matcap, Texture, Displace, Normal }