Hello!
console.log(line1.material.pluginManager._plugins)
const material2 = line1.material.clone()
console.log(material2.pluginManager._plugins)
#H1LRZ3#29
Thank you!
Hello!
console.log(line1.material.pluginManager._plugins)
const material2 = line1.material.clone()
console.log(material2.pluginManager._plugins)
#H1LRZ3#29
Thank you!
This PR will fix the problem:
Hello!
This causes issues for me:
because the constructor of GreasedLinePluginMaterial
is
constructor(
material: Material,
private _scene: Scene,
options: GreasedLineMaterialOptions
) {
and the Instantiate doesnāt set any parameters, obviously.
Iāll make the constructor working even without these parameters.
OK, seems to be working now
Cloning successful!
For ES6 to work, I think you will need to add this line at the end of the plugin file:
RegisterClass("BABYLON.GreasedLinePluginMaterial", GreasedLinePluginMaterial);
With this import:
import { RegisterClass } from "../Misc/typeStore";
Its working fine without this stuff. Iāve even created a cloning example PG and put it in the docs.
Even when using ES6? In ES6, thereās no āBABYLONā namespace, and so āBABYLON.GreasedLinePluginMaterialā should not be found, so Tools.Instantiate("BABYLON." + pluginClassName)
should not work.
Note that it is not the cloning that will fail, but the serialization + parsing (Tools.Instantiate("BABYLON." + pluginClassName)
is done in the Parse function).
Ehm, I just tried it in the Playground, where the BABYLON namespace is available. Now I get what did you mean. I am going to have a look at it.
This was absolutely correct! Iāve looked into another classes and itās done this way.
RegisterClass
has been added to GreasedLinePluginMaterial
.
Many thanks!
Iām sorry to be here again and bother you all ļ¼ļ¼ļ¼
It seems that I have also encountered the problem that the material plugin will not work after cloning, I can confirm that the source material plugin is able to work normally, the following is part of my codeļ¼
const mesh = this.scene.getMeshByName(meshName) as AbstractMesh;
if (!mesh) return;
const originMat = mesh.material as PBRMaterial
const cloneMat = originMat.clone(originMat.name)
console.log(originMat.pluginManager?._plugins, 'origin');
console.log(cloneMat.pluginManager?._plugins, 'clone');
cloneMat.backFaceCulling = !Boolean(result)
if (result) {
const color = Color3.FromHexString("#b72801");
cloneMat.alpha = 0.2;
cloneMat.emissiveColor = color;
mesh.material = cloneMat;
} else {
mesh.material = originMat;
cloneMat.dispose()
}
By comparing console, I found some anomaliesļ¼
the āoriginā means the source material
the ācloneā means cloned material
Are these the root causes of the cloned material plugin not working?
You have to implement the serialize
and parse
methods for the cloning to work as expected, as well as register your plugin with the BABYLON namespace (BABYLON.RegisterClass(...)
).
For eg, this PG doesnāt work when cloning the boom box material:
The boom box should be red.
Hereās the fixed PG:
Let me know if it fixes it for you.
Could you tell me what the serialize and parse methods need to do?
MaterialPluginBase also has little introduction about serialize and parse so that I can do the right thing with my plugins
Here is some of my plug-in code
export class CarPaintPlugin extends MaterialPluginBase {
static PLUGIN_NAME = 'CarPaintPlugin';
static _globalEnabled: boolean = false;
static useScanEffect: boolean = false;
static useClipEffect: boolean = false;
static useRainEffect: boolean = false;
static scanDirection: { value: number } = { value: 1 };
static steps: { value: number } = { value: -1 };
static sharedTime: { value: number } = { value: 0 };
private static _instances: Set<CarPaintPlugin> = new Set();
public iResolution: Vector3 = new Vector3(512, 512, 1.0);
constructor(material: PBRMaterial) {
super(material, CarPaintPlugin.PLUGIN_NAME, 200, {
USE_SCAN_EFFECT: false,
USE_CLIP_EFFECT: false,
USE_RAIN_EFFECT: false,
});
CarPaintPlugin._instances.add(this);
this._enable(CarPaintPlugin._globalEnabled);
}
static set globalEnabled(enabled: boolean) {
if (this._globalEnabled === enabled) return;
this._globalEnabled = enabled;
this._instances.forEach(instance => {
instance._enable(this._globalEnabled);
instance.markAllDefinesAsDirty();
});
}
static get globalEnabled(): boolean {
return this._globalEnabled;
}
serialize() {
}
parse(){
}
dispose() {
CarPaintPlugin._instances.delete(this);
CarPaintPlugin._instances.clear();
super.dispose();
}
isCompatible(shaderLanguage: ShaderLanguage) {
}
prepareDefines(defines: MaterialDefines, _scene: Scene, _mesh: AbstractMesh): void {
defines.USE_SCAN_EFFECT = CarPaintPlugin.useScanEffect;
defines.USE_CLIP_EFFECT = CarPaintPlugin.useClipEffect;
defines.USE_RAIN_EFFECT = CarPaintPlugin.useRainEffect;
}
getUniforms(_shaderLanguage?: ShaderLanguage): UniformTypes {
return 'xxx'
}
bindForSubMesh(uniformBuffer: UniformBuffer, _scene: Scene, _engine: AbstractEngine, _subMesh: SubMesh): void {
updateXXX()
}
static getClassName(): string {
return 'CarPaintPlugin'
}
getCustomCode(_shaderType: string, _shaderLanguage?: ShaderLanguage): Nullable<{ [pointName: string]: string; }> {
return 'xxx'
}
}
serialize
should save the current state of the plugin, and parse
reconfigure the plugin with the states passed in parameter.
However, as you only use static parameters, you basically donāt have anything to do, except enabling/disabling the plugin in the parse
method, according to the _globalEnabled
value at that moment.
If that still doesnāt work for you, I think we will need a repro in the Playground to be able to help more.
Ok, I will try. If the problem still cannot be solved, I will implement a copy of the playground
Iām sorry, Iām here again
After testing, using static parameters does not make the cloned material plugin work
Here is a simple playground
When line 45 is commented, The boom box is red.
That tells the story
Using a static variable for āglobalEnableā doesnāt work:
globalEnable = true
if (ColorifyPluginMaterial.globalEnable === enabled) {
return;
}
So, you should either remove these lines or donāt make isEnabled
static.