Away3d - freezes while new models enter camera view

I’ve noticed the following problem while creating new objects in Away3D (WebGL):

Assuming a new 3d model / text is being created and added to DisplayList outside camera view. At the exact time, that the newly created object enters camera view (eg. the object moves into camera view or camera rotates towards the object), there are some little freezes going on.

The same effect occurs regardless of:

  • view resolution (tested also on very low resolutions)
  • object poly count
  • lights on/off
  • models with/without textures

When the camera „sees” the object at least once, the freezes don’t occur anymore while entering camera view.

Did anyone figure out how to avoid such problem?

I wonder what would happen if you had an invisible ObjectContainer3D within the camera view and then added your new model mesh as a child of that object, but offscreen. Perhaps the freeze would happen right away and then allow you to smoothly pan the child into view.

I delved into this a little more for my own curiosity. I think the solution lays in whether the Mesh is considered to be in the camera frustum. Classes like the SkyBox have a special override which forces this test to always be true. Instead of creating a Mesh, it may work if you create a ForcedRenderMesh with this code:

import away3d.core.partition.MeshNode
import away3d.entities.Mesh;

class ForcedRenderMesh extends Mesh{
	public function new(geometry:Geometry, material:MaterialBase = null)	{
		super(material, geometry);
	}
	override private function createEntityPartitionNode():EntityNode
	{
		var node:EntityNode = new MeshNode(this);
		
		return new ForcedRenderMeshNode(this);
	}
}

class ForcedRenderMeshNode extends MeshNode{
	public function new(mesh:Mesh)
	{
		super(mesh);
	}
	override public function isInFrustum(planes:Vector<Plane3D>, numPlanes:Int):Bool
	{
		//same as in SkyBoxNode
		return true; 
	}
}
2 Likes

Use this with the caveat that now your objects will be constantly rendering whether on or off screen.

‘Confidant’, you were right. The problem can be bypassed by indicating that every model in the scene is currently in the camera frustum.

Of course permanent rendering of each poligon of all models would disrupt performance. Especially where there would be multiple objects in front of camera and lights would be on, one could definitely see a difference in objects animation smoothness.

So my first thought was to add a switcher in order to have a capability of turning on/off rendering of all objects at any given time:

CustomClass.hx:

package away3d;

class CustomClass{

    static public var render_all:Bool = false;
}
MeshNode.hx:

package away3d.core.partition;

import away3d.core.math.Plane3D;
import away3d.CustomClass; 


override public function isInFrustum(planes:Vector<Plane3D>, numPlanes:Int):Bool
{
		
	// check if rendering of all models in the scene is turned on
	if (CustomClass.render_all)
		return true;


	// - the below code is copied from EntityMode (superclass) / IsInFrustum() 
	if (!_entity.isVisible)
		return false;
		
	return _entity.worldBounds.isInFrustum(planes, numPlanes);
}

inside working script:

// turn on rendering
CustomClass.render_all = true;

// wait 0 sec for normal models / 0.5 – 1 sec for high poly objects

//camera starts panning / model moves towards camera view

//movement finished

// turn off rendering
CustomClass.render_all = false;

The above works – there are no freezes any more.

But… I’ve noticed some interesting thing:

when you turn on rendering of all models, wait a little and turn off before camera sees the newly created object, there are no freezes as well. So there is no need to keep rendering on, while camera rotates or object animates towards camera view.

The next step would be to find a way of checking if newly created model is already rendered before using it in the scene.

What do you think ‘Confidant’?

1 Like

Glad you’re making progress! I am wondering if checking if it’s rendered is the way to go. I’d be more inclined to force a render using _view.render() (where _view is an instance of View3D). Then you know it’s rendered and can do what you want.

Just in case you didn’t know, this forum is the best place for new discussion on Away3D, but there is still the old Flash / AS3 forum for the old version of Away3D which has useful information also. Away3D Forum

All the above tests were made with the use of view.render() as following:

var view:View3D;

Lib.current.addEventListener(Event.ENTER_FRAME, render);

function render(event:Event):Void {

	view.render(); 
}

The problem is that high poly objects need some time to render (0.5-1 sec), that’s why I suggested using a pause before the object enters camera view.

So now I’m going to try removing the need of using pause from the above solution.

PS: yes, I know the old Away3d forum - I’m a Flash survivor :slight_smile:

1 Like

Hey @klinek,

Without having a direct example in front of me to dig into, my gut feeling is that it may be related to the need to build the data buffers required for rendering, which are possibly only generated at the time they are needed (e.g. within the frustum). But I could be wrong as it’s been a good while since I’ve looked into the rendering code for Away3D.

When the object needs to be rendered (on screen), the poly/uv data needs to be constructed into array buffers suitable for uploading to the GPU and then uploaded, which in itself, takes some time and can cause a pause as the GPU receives the info. The more poly’s there are, the longer the time it will take to build the vertex buffer, indices and UV buffers (if textures are used) and subsequent upload.

Off the top of my head, I’m not sure if there is any direct mechanism in Away3D to ‘pre-generate’ and upload the buffer data other than perhaps ‘faking’ it. Using the ‘force render’ code you’ve used above, is it possible to flag all the objects to render just once (rather than all the time) and then see if that ‘populates’ the buffers for subsequent renders? Once the data is pushed to the GPU then subsequent rendering should be smooth - but there are circumstances where the data can be ‘invalidated’ and will need to re-upload to the GPU.

Again, it’s been a very long time since looking at the rendering pipeline for Away3D, so I apologise for being wrong (it’s a Friday and I’ve had a few beers as well).

Good luck.

Greg

1 Like

Having beers and browsing the OpenFL forum. What a great way to spend Friday evening!

2 Likes