-
Notifications
You must be signed in to change notification settings - Fork 150
Description
If you set onBeforeCompile to itself or to that of another derived material, the setter for that property will assign it to this[privateBeforeCompileProp], and the function will call itself infinitely.
For example:
const customMaterial = createDerivedMaterial(
baseMaterial,
{
// ...
}
)
const clonedMaterial = customMaterial.clone()
clonedMaterial.onBeforeCompile = customMaterial.onBeforeCompile;The reason this came up for me is that I needed to clone some materials, including the callbacks. Three.js Material .clone() does not copy callbacks, so I had to write my own code to do it. I tried checking with Object.hasOwn to avoid copying the callback function if it's on the prototype, but it doesn't work here. So I can't find a good workaround.
You could easily check against setting the function to itself by making a change like this:
onBeforeCompile: {
get() {
return onBeforeCompile
},
set(fn) {
if (fn !== onBeforeCompile) {
this[privateBeforeCompileProp] = fn;
}
}
},...but that won't work if you copy it over from another material. Another option might be to put every internal onBeforeCompile function in a shared WeakSet and check that. Or tag it somehow by adding a property.