Engine: WebGL2
Version: 7.54.1
OS: Windows 10
Browser: Chromium
Playground:
Desc:
When using needDepthPrePass on material with a lot of meshes, the performance went very slow.
A quick profile shows that MaterialDefines.toString() is called every frame, which (and its callers) takes maybe most the time of the frame.
So if nothing critial changed, MaterialDefines.toString() should not be called every frame, if needDepthPrePass requires a different MaterialDefines, could it be also cached like the default one?
Unfortunately, this is a by-product of using needDepthPrePass, because the effect must be recreated to take into account the change in the state of the engine between the two renderings of the (sub)mesh (we render the (sub)mesh twice when needDepthPrePass=true)…
The code is:
if (transparent) {
const material = subMesh.getMaterial();
if (material && material.needDepthPrePass) {
const engine = material.getScene().getEngine();
engine.setColorWrite(false);
engine.setAlphaMode(Constants.ALPHA_DISABLE);
subMesh.render(false);
engine.setColorWrite(true);
}
}
subMesh.render(transparent);
I can’t see any easy way to improve it. cc @sebavan and @Deltakosh, we may have to think about it.
Frame graph won’t help here, because it is too low-level (it’s inside the render method of the RenderingGroup class).
We may be able to do something by using an additional render pass id and switch to it when we render the submesh to the depth buffer (and switch back to the current render pass id afterwards). Let’s discuss it during our next sync.
No, we cannot use cloned material because if the user modifies the original material after the clone has been created, the modifications will not be reflected in the clone, which could generate erroneous values in the depth buffer if these modifications affect it.