babbleon

Scene displays before material changes are ready

Recommended Posts

Hello,

Below is a PG for a scene I'm having problems with:

https://playground.babylonjs.com/#X6KVNY

I have a list of material definitions in JSON which I load with assetsManager, once this is loaded.. I then load a .babylon file. We then loop through each of the materials in the JSON file and if the material name matches that in the scene, it then change that material.

Problem is, the scene displays  before all the textures have loaded.. more noticable if you throttle the speed.

In an ideal world, the spinning loading screen would show right up to the point that everything is ready, but I can't quite work out what I need to do.

Yes, the textures & AO map are large, but this is really just to illustrate the problem better. 

Any help would be gratefully received.

Thank you

Share this post


Link to post
Share on other sites

Hiya B.

https://playground.babylonjs.com/#X6KVNY#1

Just goofing around.  Probably bad ideas.

In line 35, I set activeCamera.fov to 0.

In lines 61-63, I restore that field of view to default (2 seconds after loading screen ends).

Sort of like... closing the iris on the camera until...  we want it to open.  :)

This might work, but perhaps it is a bad solution.  Stay tuned for better ideas from people smarter than I.

Share this post


Link to post
Share on other sites

Thank you Wingnut,

Good idea, but if I throttle the speed to 3G on chrome, your 2 second timeout isn't enough.

I need to account for fast / slow data & fast / slow computers too.

Ideally, I would need to be able to check if the shader(s) is /  are ready and that is my sticking point.

 

Share this post


Link to post
Share on other sites

Yeah.  It almost seems like you need to refuse to close the loading screen... until you have iterated thru all scene.textures.isReady() or something like that.

Is there any way to allow the assetsManager textureTask... to do all the texture loading?  Then use the "directives" in the JSON as instructions for how to apply those material adjustments/textures?

Is "the wait"... waiting for the two Babylon.Texture loads that are "ordered" by JSON "parts"?  (approx lines 48 and 56)

If you could let a AssetsManager textureTask do those two Texture loads, would the problem be gone?

Sorry, I'm really not qualified to be working on this.  :)  Feel free to ignore me, at will.

Share this post


Link to post
Share on other sites

Hey Wingnut,

Slightly ignoring what you kindly wrote... except to say that the delay in display is not due to texture loading, it's to do with the shader being ready in time.

Think I'm right in saying that 

However, I have semi-sorted it:

https://playground.babylonjs.com/#X6KVNY#2

It display a loading screen when loading JSON and then another before the scene is ready... lines 62-72:

scene.registerBeforeRender(function()
	{
		if (!scene.isReady())
		{
			engine.displayLoadingUI();
		}
		if (scene.isReady())
		{
			engine.hideLoadingUI();
		}
	})

Now, all I need to do it to get one seamless uninterrupted loading screen. Any bright ideas?

Scratch that! It doesn't work!

 

Edited by babbleon
suggestion didnt work

Share this post


Link to post
Share on other sites

Hello !

I think you may use the 'onSuccess' callback of your sceneLoader to do your material changes.
This way, the scene is not ready.
Then, you just have to stop the renderLoop if the scene is not ready, and wait until it is ready to start it again.

I was not able to test it, because well.. my internet connection is too fast (I can't believe I am actually complaining about that).
https://playground.babylonjs.com/#X6KVNY#4
 

I guess you can also force the LoadingUI to be displayed instead of stoping the renderLoop
https://playground.babylonjs.com/#X6KVNY#5

I think that in your own code (working out of the playground) might be easier as you have complete control on the moment you launch the renderLoop.
 

Share this post


Link to post
Share on other sites

I think I have sorted this. Can't show all of it in PG, so have pasted below in case anyone else can make use of it.

var createScene = function()
{
	engine.enableOfflineSupport = false;

	var scene = new BABYLON.Scene(engine);

	var camera = new BABYLON.ArcRotateCamera('Camera', null, null, null, BABYLON.Vector3.Zero(), scene);
	camera.setPosition(new BABYLON.Vector3(1.00, 1.00, -1.50));
	camera.minZ = 0;
	camera.panningDistanceLimit = 1;
	camera.pinchPrecision = 60.00;
	camera.wheelPrecision = 60.00;
	camera.upperAlphaLimit = (Math.PI * (90.00 + 270) / 180);
	camera.lowerAlphaLimit = (Math.PI * (-90.00 + 270) / 180);
	camera.upperBetaLimit = 95.00 * (Math.PI / 180);
	camera.lowerBetaLimit = 0.00 * (Math.PI / 180);
	camera.lowerRadiusLimit = 0.50;
	camera.upperRadiusLimit = 2.00;
	camera.target = new BABYLON.Vector3(0.00, 0.30, 0.00);
	camera.fov = 50.00 * (Math.PI / 180);
	camera.attachControl(canvas, false);

	var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 4, 0), scene);
	light.intensity = 0.7;

	var assetsManager = new BABYLON.AssetsManager(scene);
	//load json file with specification for each material to be applied
	var textTask = assetsManager.addTextFileTask('materialsjson', 'https://raw.githubusercontent.com/babbleon/babylon/master/materials.json');
	assetsManager.load();
	textTask.onSuccess = function(task)
	{
		parts = JSON.parse(textTask.text).material;
		//babylon file has materials, but all are white
		BABYLON.SceneLoader.Append('', 'https://raw.githubusercontent.com/babbleon/babylon/master/testcubes.babylon', scene, function()
		{
			for (var i = 0; i < parts.length; i++)
			{
				for (var j = 0; j < scene.meshes.length; j++)
				{
					//loop thru each mesh's material and if it matches that in the json file, then we change it
					if (scene.meshes[j].material.name === parts[i].par_path)
					{
						//rand added to texture path to avoid caching on playground
						scene.meshes[j].material.diffuseTexture = new BABYLON.Texture('https://raw.githubusercontent.com/babbleon/babylon/master/' + parts[i].mat_id + '.jpg?rand=' + Math.round(Math.random() * 100000), scene);
						scene.meshes[j].material.diffuseTexture.coordinatesIndex = 1;
						scene.meshes[j].material.diffuseTexture.uScale = 5;
						scene.meshes[j].material.diffuseTexture.vScale = 2;
						scene.meshes[j].material.diffuseColor = BABYLON.Color3.FromHexString(parts[i].mat_diffuseColor);
						scene.meshes[j].material.specularColor = BABYLON.Color3.FromHexString(parts[i].mat_specularColor);
						scene.meshes[j].material.ambientColor = BABYLON.Color3.FromHexString(parts[i].mat_ambientColor);
						scene.meshes[j].material.emissiveColor = BABYLON.Color3.FromHexString(parts[i].mat_emissiveColor);
						scene.meshes[j].material.ambientTexture = new BABYLON.Texture('https://raw.githubusercontent.com/babbleon/babylon/master/Job%201_FULL.png', scene);
						scene.meshes[j].material.ambientTexture.coordinatesIndex = 0;
					}
				}
			}
		});
	}
	return scene;
};

var scene = createScene();
engine.runRenderLoop(function()
{
	if (!scene.isReady())
	{
		engine.displayLoadingUI();
	}
	if (scene.isReady())
	{
		scene.render();
	}
});

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.