Large lag when an object appears in the view

loaders
webgl-renderer

#1

Dear all,
I have an application based on Three.js that loads/unloads objects in the world (for LOD, streaming and various other reasons). I made my best to avoid lags while the user is navigating the scene for example using web workers to download the new objects (i.e., the WWOBJLoader2).
What I found out is that, despite of this, there is a large lag when a new object first appears in the view (not when it is loaded in memory by the Loader). My question is: does threejs send the object (and its texture) to the graphic card when it first appears in the scene? Is it that lag that I am experiencing? Is it something related to the geometry, the texture, some processing or…?
Is there any way to avoid this lag?
When I say “lag” I mean that it freezes the controller (and it is very annoying for the user).
Thanks!


Update vertices and color of thousands of meshes - asking for a strategy
#2

I dont really know, but if the object has a lot of children, i fought this by limiting the amout of children displayed… in the end to looked real bad.


#3

It shouldn’t be my case: I have a very flat arrangement, every object is a child of the root and there are 60 objects in the scene (each one with its texture). The whole scene contains about 3 millions vertices and 1 million faces.


#4

Yes, assuming you’ve never used the corresponding material and texture before. The compilation of the shader program takes some times, also the texture decode and upload. The resulting lag is in general visible for the user since the corresponding frame time is comparatively long.

You can try to use WebGLRenderer.compile in order to improve your performance. But this only works if your materials are already part of the scene.


#5

I should probably open another question and not revive this topic. But just to clarify, is it as easy as scene.add(material) to ‘pre-add’ the material that will/may be needed and then retrieve it when I create the mesh var mesh = new THREE.Mesh( geometry, scene.getObjectByName(object.name); where object.name is the name of the material. Or would that be nonsense and bad for performance?


#6

Pretty sure you can only add an Object3D to a scene and not a material directly. You probably could create a Mesh or something and assign it your material and add the mesh to the scene. This may not work though as it will still need to be in camera frustum to push to gpu. There probably (hopefully) is a better way to do this as I too would like to just push everything at once to the gpu and avoid this lag when the scene is initially complete.

Maybe disable frustum culling on all objects for their first frame? Not sure if that would work.


#7

Just to clarify, you can’t add a material directly to the scene graph. It has to be a property of a 3D object like a mesh.

That does only work if the object is part of the scene graph. In this case, I would use WebGLRenderer.compile().


#8

I tried WebGLRenderer.compile() but it kept crashing my app for some reason.

This is what I am using now:

this.mesh.frustumCulled = false;

var self = this;

this.mesh.onAfterRender = function(){
	
	self.renderCount++;
	
	if( self.renderCount >= 1 && !self.mesh.frustumCulled ){
		
		self.mesh.frustumCulled = true;
		
	}
	
};

this being an object that I assign the mesh itself to in this case. But as Mugen87 mentioned, if the object is dynamically added to the scene at runtime with materials/attributes that have not yet been passed to the gpu, you will get some lag as it loads regardless if its in view or not.

Not a perfect solution, but I am happy with it.


#10

Updated to this:

mesh.frustumCulled = false;

mesh.onAfterRender = function(){
	
	mesh.frustumCulled = true;
	
	mesh.onAfterRender = function(){};
	
};