Babylon.js: SceneOptimizer: "Positions are required"

Created on 18 Jun 2018  路  17Comments  路  Source: BabylonJS/Babylon.js

Bugs

App works fine if not using SceneOptimizer.

When activating SceneOptimizer, I get an error "Positions are required", which is coming from this file: https://github.com/BabylonJS/Babylon.js/blob/a0afb803db41aa578c8adb04971cca4848765a54/src/Mesh/babylon.mesh.vertexData.ts#L466

Whether I do:

public async createScene(): Promise<void> {
  this.scene = new Scene(this.engine);

  this.optimizeScene();
}

private optimizeScene() {
  const optimizationSettings = SceneOptimizerOptions.ModerateDegradationAllowed();
  optimizationSettings.targetFrameRate = 30;

  SceneOptimizer.OptimizeAsync(
    this.scene,
    optimizationSettings,
    () => { ... },
    () => { ... },
  );
}

Or:

public async createScene(): Promise<void> {
  this.scene = new Scene(this.engine);

  this.scene.whenReadyAsync().then(
    () => this.optimizeScene()
  )
}

private optimizeScene() {
  const optimizationSettings = SceneOptimizerOptions.ModerateDegradationAllowed();
  optimizationSettings.targetFrameRate = 30;

  SceneOptimizer.OptimizeAsync(
    this.scene,
    optimizationSettings,
    () => { ... },
    () => { ... },
  );
}

I get the error.

Not 100% sure that's a bug, I might be missing something but as it's perfectly working when I do not use the SceneOptimizer I'm suspicious.

help wanted

All 17 comments

Hello!
Can you provide a repro on the playground?

Hi, I tried to create a repro, but it worked for me. @maxime1992 - can you check if I missed something (added game.ts file from docs for reference )?
Thanks
game.txt

Hey @ssaket, thanks for trying to repro.

Looks fine to me. Are you running it on a good laptop/computer?

It's happening only when there's a need to make a degradation to the rendered view.
So if your laptop is powerful enough, then you won't notice (that's why my E2E tests were passing just fine locally but ended up with an error on CI).

To keep the optimisations but avoid the problem, we've ended up using a custom degradation function:

function customDegradationAllowed(targetFrameRate?: number): SceneOptimizerOptions {
  const result = new SceneOptimizerOptions(targetFrameRate);

  let priority = 0;

  // broken due to https://github.com/BabylonJS/Babylon.js/issues/4558
  // result.optimizations.push(new MergeMeshesOptimization(priority));
  result.optimizations.push(new ShadowsOptimization(priority));
  result.optimizations.push(new LensFlaresOptimization(priority));

  // next priority
  priority++;
  result.optimizations.push(new PostProcessesOptimization(priority));
  result.optimizations.push(new ParticlesOptimization(priority));

  // next priority
  priority++;
  result.optimizations.push(new TextureOptimization(priority, 512));

  // next priority
  priority++;
  result.optimizations.push(new RenderTargetsOptimization(priority));

  // next priority
  priority++;
  result.optimizations.push(new HardwareScalingOptimization(priority, 2));

  return result;
}

And then calling it like that:

```typescript
private optimizeScene() {
const optimizationSettings = SceneOptimizerOptions.ModerateDegradationAllowed();
optimizationSettings.targetFrameRate = 30;
const targetFrameRate = 30;
const optimizationSettings = customDegradationAllowed(targetFrameRate);

SceneOptimizer.OptimizeAsync(
  this.scene,
);

}
```

As you can see, commenting out the line with MergeMeshesOptimization is enough.
That narrows down the problem I guess.

I see. @deltakosh any inputs ?

Well my question remains:) I need a repro to fix it. The code seems OK when I run it locally so I need @maxime1992 to provide a sample code that highlight the issue and not just a few lines of codes because we don't have the context else

What do you have in you scene for instance? Created objects? Loaded ones?

Also to force the system to always optimize you can create it with a target of 70fps:)

I did a repro here:
https://www.babylonjs-playground.com/#4C27TZ#1

But it works :(

@maxime1992 Can you update it to help reproing the issue?

I tested it on an android phone(mid-specs) and it works well, Could you also provide thedevice specs on which it is failing. -Thanks @deltakosh for creating the playground.

Good Day !

Test device :(Processor: Snapdragon 810 Octa-core, 1.8GHz, GPU: Adreno 430 GPU)

@deltakosh thanks for trying to repro. I do not feel very comfortable yet with Babylon to help as much as I would.

I've tested it and indeed it's working on my machine too. I have no idea what's going wrong within our app with MergeMeshesOptimization.

That said, maybe that one of my coworker might be able to give you more information but not before 1 week from now.

EDIT:
I don't know if that can be of any help but failures happened while the app was under test with Cypress. That might be related to electron config maybe (?)

Well this would be weird because the bug seems geometry related.
I keep the bug open for now to see if your co-workers can help reproducing it:)

Any chance to have a repro?

Hi. As I said earlier: one of my coworker might be able to give you more information but not before 1 week from now. So it'll not be before 2~5 of July. I haven't played much with Babylon so I really don't know where to start with that. Can't really help on my side for now =x

Ok no worry..I'll check back early july then :)

@deltakosh an update (I'm that aforementioned coworker). We're able to consistently reproduce the issue within our system, however I'm having a hard time narrowing it down to a simplified reproduction, preferably on the sandbox. The symptoms I'm seeing is that the VertexData.merge function is being called on a pair of meshes that previously had geometry, but when called can be seen to not have any _geometry value (it is null). I'll continue to investigate why the geometry has been nullified, and keep you posted.

Ah hah! Ok I should have waited before posting that comment (though writing it made me think about it in a different way).

So the issue arises because some of the meshes trying to be merged have been disposed. I think maybe a simple test that the meshes are not disposed before trying to merge them might solve this

@deltakosh I managed to get a repro at last. Unfortunately I can't save it in the playground as I'm getting a 500 error?

Here's the code anyway:

var createScene = function () {

    // This creates a basic Babylon Scene object (non-mesh)
    var scene = new BABYLON.Scene(engine);

    // This creates and positions a free camera (non-mesh)
    var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene);

    // This targets the camera to scene origin
    camera.setTarget(BABYLON.Vector3.Zero());

    // This attaches the camera to the canvas
    camera.attachControl(canvas, true);

    // This creates a light, aiming 0,1,0 - to the sky (non-mesh)
    var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);

    // Default intensity is 1. Let's dim the light a small amount
    light.intensity = 0.7;

    // Our built-in 'sphere' shape. Params: name, subdivs, size, scene
    var sphere = BABYLON.Mesh.CreateSphere("sphere1", 16, 2, scene);
    var sphere2 = BABYLON.Mesh.CreateSphere("sphere2", 12, 1.5, scene);
    var sphere3 = BABYLON.Mesh.CreateSphere("sphere2", 8, 1, scene);

    sphere.position.y = 1;
    sphere2.position.y = 2;
    sphere3.position.y = 3;

    // Our built-in 'ground' shape. Params: name, width, depth, subdivs, scene
    var ground = BABYLON.Mesh.CreateGround("ground1", 6, 6, 2, scene);

    const optimizationSettings = BABYLON.SceneOptimizerOptions.ModerateDegradationAllowed();
    optimizationSettings.targetFrameRate = 70;

    sphere2.parent = sphere;
    sphere3.parent = sphere2;

    BABYLON.SceneOptimizer.OptimizeAsync(
        this.scene,
        optimizationSettings,
        () => { 
            console.log("done")
        },
        () => { 
            console.log("failed")
        },
    );

    return scene;

};
Was this page helpful?
0 / 5 - 0 ratings