kmitov
October 8, 2019, 10:27am
1
I would like to make a mesh blink. Since it is sharing material with another mesh I must duplicate the material.
BABYLON.SceneLoader.Load("/assets/", "map.gltf", engine, function (newScene) {
const mesh = newScene.getMeshByID("6558.dat.001")
console.log(mesh)
try {
mesh.material = mesh.material.clone()
} catch(err) {
console.log(err)
}
});
This results in
TypeError: Cannot set property material of [object Object] which has only a getter
How can I make this mesh blink?
Thanks.
Update:
Trying to registerInstancedBuffer following
https://doc.babylonjs.com/how_to/how_to_use_instances
but an error occurs:
mesh.registerInstancedBuffer is not a function
What I end up doing is cloning all the meshes when I need them to blink and disposing them when I don’t
This is terrible for performance and It is slow.
const meshes = []
babylonNode.getChildMeshes().forEach((mesh) => {
if(mesh.getClassName() == "InstancedMesh") {
const newMesh = mesh.sourceMesh.clone(mesh.name+"blink_tmp", mesh.parent)
newMesh.position = mesh.position.clone();
if(mesh.rotationQuaternion)
newMesh.rotationQuaternion = mesh.rotationQuaternion.clone();
newMesh.scaling = mesh.scaling.clone();
meshes.push(newMesh);
} else {
const newMesh = mesh.clone(mesh.name+"blink_tmp", mesh.parent)
newMesh.position = mesh.position.clone();
if(mesh.rotationQuaternion)
newMesh.rotationQuaternion = mesh.rotationQuaternion.clone();
newMesh.scaling = mesh.scaling.clone();
meshes.push(newMesh);
}
});
You should keep your instances because they are good for performance
To make an instance blink you were correct by using the new InstancedBuffer. But you need to be on the latest preview version (as this is a brand new feature)
Something like that should work: https://www.babylonjs-playground.com/#YPABS1#1
kmitov
October 8, 2019, 4:52pm
3
Thanks.
When I was trying it today I was at the latest preview, or at least I think so
This should get me the latest preview, right?
<script src="https://preview.babylonjs.com/babylon.js"></script>
<script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
<script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
<script src="https://preview.babylonjs.com/nodeEditor/babylon.nodeEditor.js"></script>
<script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
<script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
<script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
<script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
<script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
kmitov
October 8, 2019, 4:53pm
5
Any suggestion why I got if I was at the latest preview. Anything I could do?
mesh.registerInstancedBuffer is not a function
It was published yesterday so you may have missed the update
kmitov
October 8, 2019, 5:18pm
7
I am doing it right now.
if(mesh.getClassName() == "InstancedMesh") {
mesh.registerInstancedBuffer("color",4)
as shown at
https://doc.babylonjs.com/how_to/how_to_use_instances
and the error is:
Uncaught TypeError: mesh.registerInstancedBuffer is not a function
```
## Update
Importing as
You must have something wrong on your side as the demo I linked before (https://www.babylonjs-playground.com/#YPABS1#1 ) is working and it is using preview as well
kmitov
October 8, 2019, 6:19pm
9
I see the example
I’ve reproduce the problem on the example and I check mesh.registerInstancedBuffer is undefined:
if(mesh.getClassName() == "InstancedMesh") {
console.log(mesh.registerInstancedBuffer)
}
https://www.babylonjs-playground.com/#YPABS1#5
The method is undefined.
The console logs
Babylon.js v4.1.0-alpha.24 - WebGL2 babylon.js:16:426120
undefined 76 main.js line 98 > eval:50:25
kmitov
October 8, 2019, 6:51pm
10
I think I understand the idea of the registerInstancedBuffer but it should be called while loading the GLTF and not after that. Am I right?
kmitov:
registerInstancedBuffer
Oh gotcha, this is a MESH function. You have to call it to enable the instanced buffers (like in the example). After that all instances will receive the new property (instance.instancedBuffer.color here)
It can be done afterwards
kmitov
October 9, 2019, 3:42am
13
Changed and doing it afterwards and calling on the sourceMesh.
if(mesh.getClassName() == "InstancedMesh") {
mesh.sourceMesh.registerInstancedBuffer("color",4)
And the following error occurs:
Uncaught TypeError: Cannot read property 'toArray' of null
at t.s.a._processInstancedBuffers (babylon.js:16)
at t._renderWithInstances (babylon.js:16)
at t._processRendering (babylon.js:16)
at t.e._renderSubMesh (babylon.js:16)
at _mainTexture.customRenderFunction (babylon.js:16)
at e.render (babylon.js:16)
at e.render (babylon.js:16)
at t.renderToTarget (babylon.js:16)
at t.render (babylon.js:16)
at e._renderMainTexture (babylon.js:16)
Can you repro in the playground?
kmitov
October 9, 2019, 4:43am
15
Trying to, but the only difference I could see for now is that in my case the gltf scene is the main scene.
I am not creating a default scene. I am creating the engine, loading the gltf and from then on using the scene from the Load method.
How can I return the scene from the gtlf method in the playground. Can I return a promise that would resolve a scene in the playground instead of returning the scene?
Yes if the function return a promise
kmitov
October 9, 2019, 10:09am
17
Reproduced in the playground - https://www.babylonjs-playground.com/#YPABS1#11
Exception is
TypeError: this.instancedBuffers[n] is null
_processInstancedBuffers https://preview.babylonjs.com/babylon.js:16
_renderWithInstances https://preview.babylonjs.com/babylon.js:16
_processRendering https://preview.babylonjs.com/babylon.js:16
render https://preview.babylonjs.com/babylon.js:16
render https://preview.babylonjs.com/babylon.js:16
renderUnsorted https://preview.babylonjs.com/babylon.js:16
render https://preview.babylonjs.com/babylon.js:16
render https://preview.babylonjs.com/babylon.js:16
_renderForCamera https://preview.babylonjs.com/babylon.js:16
_processSubCameras https://preview.babylonjs.com/babylon.js:16
render https://preview.babylonjs.com/babylon.js:16
compileAndRun https://www.babylonjs-playground.com/js/main.js:135
<anonymous> self-hosted:1007
_renderLoop https://preview.babylonjs.com/babylon.js:16
<anonymous> self-hosted:1009
I suspect you are registering the buffer but not creating it like :
Yeah and you are calling clone for some reasons…
https://www.babylonjs-playground.com/#YPABS1#12
kmitov
October 9, 2019, 3:13pm
20
Thanks. clone was from another try.
To summarize for anyone with this question
check if sourceMesh has instancedBuffers
if not then register to source
Then create to source
Then create to instanced.
if(mesh.getClassName() == "InstancedMesh") {
if (!mesh.sourceMesh.instancedBuffers) {
mesh.sourceMesh.registerInstancedBuffer("color",4)
mesh.sourceMesh.instancedBuffers.color = new BABYLON.Color4(1, 0, 0, 1);
}
mesh.instancedBuffers.color = new BABYLON.Color4(1, 0, 0, 1);
}
1 Like