Example synchronous rendering loop?

We’re working on some tools for recording video from Cesium. We currently have a lot of hack-y infrastructure for pausing and resuming a flyTo (and an associated screen capture) while content loads within the default render loop. Unfortunately we (a) don’t have exact control over the timeline, (b) occasionally get off-by-one errors where content notifies us that it has finished loading, but does not appear in the immediately following frame when we unpause, and © have to use a 1/6 framerate multiplier to get an acceptable framerate in the output video, because Cesium can’t keep up with the target framerate.

We’re thinking of adding the ability to capture a 360 cubemap into our tools, which means we will need to capture 6 views-per-frame at exactly the same time-step, and at this point it seems better that we just start from scratch and write our own render loop to take exact control over the camera view, timestepping, and interleaving of content loading with renders. Is there an example, or documentation, showing all of the events/callbacks we need to fire off to update the clocks for the scene and the camera tweening, as well as to do our own checks of whether all of the content in a scene is ready to be rendered?

I’ve been digging around in the source code and it looks like this functionality is spread out all over the place.

For example https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Widgets/Viewer/Viewer.js has an onTimelineScrubFunction, but the clock being manipulated is not a member of that Viewer object (and as far as I can tell none of the Viewer, Scene, or CesiumWidgets take an explicit clock argument to their constructors).

Similarly, startRenderLoop in https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Widgets/CesiumWidget/CesiumWidget.js has a lastFrameTime local variable, which appears to track the (real-world) time since the last frame, but doesn’t appear to influence the simulation time at all.

Hi Thomas,

Rewriting the render loop seems like a huge task! There is no documentation on where exactly the render loop functionality is specifically, but we have a blog post on the Cesium Renderer Architecture, as well as some general WebGL related posts that might come in handy. Most of the logic should be happening in the Renderer layer.

Beyond that, I don’t have any specific tips for you. Hopefully one of our developers who are involved more with the renderer than I am can give some more advice.

Thanks,

Gabby

Hi Gabby -

Thanks for replying, but I think you may have misunderstood my question. I don’t need to change the logic used for rendering a particular frame, I need to control the loop that ticks the simulation time and issues calls to the renderer. The latter part is currently handled by the code here:


function startRenderLoop(widget) {

widget._renderLoopRunning = true;

var lastFrameTime = 0;

function render(frameTime) {

if (widget.isDestroyed()) {

return;

}

if (widget._useDefaultRenderLoop) {

try {

var targetFrameRate = widget._targetFrameRate;

if (!defined(targetFrameRate)) {

widget.resize();

widget.render();

requestAnimationFrame(render);

} else {

var interval = 1000.0 / targetFrameRate;

var delta = frameTime - lastFrameTime;

if (delta > interval) {

widget.resize();

widget.render();

lastFrameTime = frameTime - (delta % interval);

}

requestAnimationFrame(render);

}

} catch (error) {

widget._useDefaultRenderLoop = false;

widget._renderLoopRunning = false;

if (widget._showRenderLoopErrors) {

var title = 'An error occurred while rendering. Rendering has stopped.';

widget.showErrorPanel(title, undefined, error);

}

}

} else {

widget._renderLoopRunning = false;

}

}

requestAnimationFrame(render);

}

Which I linked in the earlier email. Unfortunately this part doesn't seem to control advancing the various simulation clocks for lighting / animation / camera tweening.

Thanks again,

Thomas

Sorry for the misunderstanding Thomas!

You can pass useDefaultRenderLoop: false as part of the options when constructing a Viewer. Then you can advance the loop yourself using Viewer.render(). The simulation time is handled by the Clock. Does that help at all?

Thanks,

Gabby

Aha, it looks like the clockStep property can be used for manual control over simulation time. Do you happen to know if the same timing values are used by tweening library for controlling camera flight, or if that just relies on the system clock?

Yes, I believe camera movement uses system time rather than simulation time. For example, if you pause the simulation, you can still move the camera or flyTo another location.