Skip to content
This repository has been archived by the owner on Apr 5, 2023. It is now read-only.

fix: children should refresh the parent #27

Closed
wants to merge 1 commit into from
Closed

fix: children should refresh the parent #27

wants to merge 1 commit into from

Conversation

drcmda
Copy link
Member

@drcmda drcmda commented Apr 13, 2022

lamina will re-create the shader on every render because "children" is not a stable reference. children should rather inform lamina on mount, and when certain props have changed that it must refresh. this of course would duplicate refresh multiple times once you're dealing with multiple layers — this draft would try to work against that.

Comment on lines +101 to +113
let hasRefreshed = false
function useRefresh<T>({ mode, visible, type, mapping, map, axes }: any) {
const ref = useRef<T>()
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
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smells like .needsUpdate 😛

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On a serious note, maybe consider inverting the logic so that it's __needsRefresh, makes the code less clumsy

//@ts-ignore
return <displace_ ref={ref} args={getNonUniformArgs(props)} {...props} />
const Displace = React.forwardRef<LAYERS.Displace, DisplaceProps>((props, forwardRef) => {
const ref = useRefresh<LAYERS.Displace>(props)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could avoid this double ref by just passing the ref to useRefresh, no?

useRefresh(forwardedRef, props)

@@ -69,14 +69,14 @@ const LayerMaterial = React.forwardRef<
LAYERS.LayerMaterial,
React.PropsWithChildren<LayerMaterialProps & Omit<AllMaterialProps, 'color'>>
>(({ children, ...props }, forwardRef) => {
const ref = React.useRef<LAYERS.LayerMaterial>(null!)
const ref = React.useRef<LAYERS.LayerMaterial & { __hasRefreshed: boolean }>(null!)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the _needsRefresh or whatever to the LayerMaterial itself? Might be generally useful to have it there, typed and all

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a needsupdate was added, when and where exactly will the material be updated? I never understood how 3JS’s needsupdate works

@FarazzShaikh
Copy link
Member

FarazzShaikh commented Apr 16, 2022

This should be fixed in #29

No more args in anything. All non-uniforms are also converted to setters, the layers then call refresh() on the material when a non unifom changes.

Also removed children and args from <LayerMaterial /> so it will not re-render needlessly

@Kevinparra535
Copy link

I'm having problems with the refresh of the LayoutMaterial, I suppose that PR solves it, when will it be available?

@FarazzShaikh
Copy link
Member

FarazzShaikh commented Jun 13, 2022

@Kevinparra535 Due to deeper underlying issues this PR has been incorporated into the upcoming 1.2.0. You can track progress of it in #29

Will be available as time openes up for me to complete the release.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants