Loading Progress

You have progress stuff in CGE bit I can’t find a way to track the progress of a scene loading into (another) test app.

Test app is basically the manual’s loading, displaying scene page with a progress bar at the bottom.

As a stress test I grabbed a high-poly model from SketchFab “Scene contains 1246027 triangles and 704604 vertices” and loaded it (takes a noticable time).

What I want to do is have some metrics from the Scene.Load with an event being fired every so often. For example view3dscene tells me the model has 1246027 triangles so an event saying e.g. 69863 triangles processed out of 1246027, or something like that, would prove useful.

I’m just after some numbers that I can translate into some feedback for the user in the same way that TDownload (when implemented) will tell me how much of a file I’ve got.

Test project with huge model at https://peardox.com/script/view3d.rar - progress bar dummied in timer event - does nothing useful, just moves a bit.

It is difficult to make a useful progress bar when loading a single model.

Loading a model involves a number of things, and their influence on the final loading time differs case-by-case:

  • loading model from disk/network
  • parsing (significant in case of XML, VRML classic, almost nothing in case of binary glTF)
  • initializing GPU shaders
  • loading vertex data to GPU buffers
  • loading texture data from file to RAM, then from RAM to GPU

These things are not always easy to “break down”, e.g. when we load a single huge Shape to GPU, it is just one big call to GPU.

Testing your model in view3dscene, log shows:

-------------------- Loading begin
Loaded "file:///home/michalis/Desktop/assets/scene.gltf" with dependencies in 7.50 seconds:
  0.33 to load from disk (create X3D graph)
  2.79 to initialize scene (initialize shapes tree, collisions...)
  4.38 to prepare resources (load textures, prepare OpenGL resources...)
-------------------- Loading end

So both “initialize scene” and “prepare resources” are important contributors here.

Adding logging

LogTextureLoading := true;
LogAllLoading  := true;

to view3dscene (see https://castle-engine.io/manual_optimization.php ) one can see with the naked eye that most time is spent on loading assets/textures/materialXXX_baseColor.jpeg (each 2048x2048 texture). So it’s not (only) about the number of triangles loaded, in this case a useful progress bar would need to take into account how many dependent files are also loaded.

( Note that you can possibly speed up the loading by converting textures to DDS or KTX formats. These are larger on disk, but require almost no processing to load them on GPU. )

I don’t yet have a better answer about “progress of loading the model”, I can only show that it’s not trivial to make such progress in a way that is useful in various practical use-cases :slight_smile:

P.S. Sorry for the delay in answering. I had a hard time last week being busy with lots of things. I’m catching up now – all questions will be answered soon :slight_smile:

The very fact that you can log some metrics is a sign that what I want to do is, at least, possible even if not a perfect solution.

A seven second loading time for the sample model with no indication that anything is happening is an undesirable ‘feature’ or any application as far as the end user is concerned.

I was playing with loading a large quantity of JSON logs yesterday, all of which need parsing and categorising. While I got the load down to < 2secs I’m far from happy with it.

I then realised what is desirable in both cases is ANY indication that SOMETHING is going on under the hood. In the case of my JSON stuff I know how many logs I’m going to process before I start working with them so I’m going to add a callback that can be used to report progress in that situation - an X out of Y logs processed sort of thing.

This same concept would also work with CGEs loading mechanism.

You have a known number of entities to process so returning some object or similar structure with something alone the lines of…

123 polys out of 65442 processed
13 faces out of 7943 processed
0 out of 73 textures processed

Would at least allow an application with some heavy processing to show it was doing something.

The next problem I hit was the reporting frequency. If, like the sample model, there are 1M+ polys you don’t want to report every single one…

If you definitely know in advance how many are going to be processed then you can report either every X operations or every X% operations (Bresenham comes in handy for the percentage feedback version)

In the case of an unknown quantity of being processed then I think that reporting every Xms works out well (once a second would do)

It is definitely possible :slight_smile: The problem here is the complexity of implementing such progress in a way that is really useful.

There are a lot of things that contribute to the loading time, some of them are not known before you start reading. E.g. triangles are processed at least 3 times (parsing, constructing mesh, uploading to GPU). Textures may be referenced from the main model as well as any referenced model (in case of X3D Inline).

The bottom line is that it is definitely possible, but it would be quite some additional work and complexity in code. Let me think about this – if I will do this, I want to implement it in a way that doesn’t add too much complexity to the (already complicated) loading code :slight_smile:

1 Like