RTT performance when swapping materials

I’m building a robot simulator here https://gears.aposteriori.com.sg and one of the component that I’m trying to simulate is the color sensor. A real color sensor uses it’s own lighting, and cancels out the effect of ambient light. To simulate that, I’m using an RTT, and swapping out the materials to one that has lighting disabled and emissiveColor set accordingly.

The materials for the RTT is prepared and saved in advanced and frozen…

  scene.meshes.forEach(function(mesh) {
    mesh.origMaterial = mesh.material;
    if (mesh.material == null) {
      mesh.rttMaterial == null;
    } else {
      mesh.rttMaterial = mesh.material.clone();
      mesh.rttMaterial.disableLighting = true;
      if (mesh.diffuseTexture) {
        mesh.rttMaterial.emissiveColor = new BABYLON.Color3(1,1,1);
      } else {
        mesh.rttMaterial.emissiveColor = mesh.rttMaterial.diffuseColor;
      }
      mesh.origMaterial.freeze();
      mesh.rttMaterial.freeze();
    }
  });

…and the RTT before and after callbacks swaps the materials…

renderTarget.onBeforeRender = function() {
  renderTarget.renderList.forEach(function(mesh) {
    mesh.material = mesh.rttMaterial;
  });
};
renderTarget.onAfterRender = function() {
  renderTarget.renderList.forEach(function(mesh) {
    mesh.material = mesh.origMaterial;
  });
};

I have expected the material swap to cause a small hit on performance, but it seems that it’s causing the FPS to drop by half compared to no swap in material. Even swapping the material for just one single mesh is causing FPS to drop massively. Is there any way to improve this performance? If not, perhaps there is a way to simulate the no shading effect without changing materials?

The problem with swapping materials for a mesh is that the effect must be recreated each time, because the effect is stored on the sub meshes, and when you switch material the current effect of a submesh is the one suitable for the previous material, not the one you have switched to.

You can speed up things by saving the effects yourself and setting the right ones based on the material you switch to. Have a look to:

https://doc.babylonjs.com/how_to/how_to_use_rendertargettexture_and_multiple_passes

Section “Performance and tips”.

Thanks! That solved the problem.

I’ve previously read the article you’ve suggested, but didn’t know what a submesh “effect” is and wrongly assumed that I don’t need it.

1 Like