Pre-emptively sending geometry buffer data to graphics memory

I’m getting a brief freeze the first time a geometry is visible (but no freeze if its hidden then reshown). [By this I mean initially the geometry is created, attached to the scene graph, but its cull hint is set to always].

From this I’m suspecting that all the buffers that make up the geometry are only sent to the graphics card the first time the geometry is visible. But this is meaning for me that when these geometries are unhidden they cause a brief frame rate drop (seemingly like the frame update is waiting for this to complete).

Assuming any of that is true, is it possible to preload geometry to graphics memory in a separate thread without that causing the frame to wait?

Afaik it is possible to preload a spatial to GPU using RenderManager.preloadScene() but I do not know if it supports loading from a different thread.

1 Like

Thank you for this! It was a combination of this and the generation of collision data for the mesh. I should be able to premptively do both and avoid my frame drop.

The collision data was being generated as I was using picking in my scene and as soon as the new object appeared it needed collision data

(thats mesh.createCollisionData())

Yeah, this is a killer. If you can aggressively avoid generating collision data then it’s always a win. (ie: if it’s an item that will never be picked then override collideWith() to do nothing)

The other common framerate killer (from someone who generates geometry and the fly all the time and knows)… is adding too many things to the scene at once.

Generate your stuff on a background thread and then add them to the scene one or two per frame.

…can even get fancy about it:

…which let’s one add jobs that will be run on the background and then run on the render thread… but only so many as budgeted.

public interface Job {

    /**
     *  Called when the Job is run on the background thread.
     */
    public void runOnWorker();
    
    /**
     *  Called on the JME render thread when the background  processing 
     *  has completed.  Returns a rough indicator of the amount of work
     *  performed relative to the amount of work that is allowed per
     *  update of the scheduler.  For example, if "finishPerFrame" is 2
     *  then this would allow 2 jobs that return 1.0, or 20 jobs that return
     *  0.1... or any number of jobs that return 0.  It's a way to limit
     *  the amount of work done on update in a way that allows 'no-ops',
     *  'lots of updates', and 'barely any updates' to be dealt with
     *  intelligently. 
     */
    public double runOnUpdate();
}```
5 Likes