RenderKit/ospray

Question on altering objects in the current active world

paulmelis opened this issue · 5 comments

A question regarding this section of the docs:

Rendering and ospCommit

The use of either ospRenderFrame or ospRenderFrameBlocking requires that all objects in the scene being rendered have been committed before rendering occurs. If a call to ospCommit happens while a frame is rendered, the result is undefined behavior and should be avoided.

Does "committed before rendering occurs" leave open the case of altering and re-committing objects in the current world after rendering has started? To be more concrete, I have an interactive render loop in which ospRenderFrame() is repeatedly called, but somewhere during that loop the scene might need to be updated (based on user input). Since canceling the current render might take a small amount of time I'd like to alter the current world and its scene objects directly after calling ospCancel(), but before waiting on ospWait(OSP_TASK_FINISHED), in order to minimize waiting time. But I'm not sure if that's supported and/or leads to undefined behaviour.

It is fine to update objects (set / change parameters) even during renderFrame, but the commit() needs to be deferred. See e.g.
apps/ospExamples/GLFWOSPRayWindow.cpp with various async calls to addObjectToCommit; and the commitOutstandingHandles happens right before the next renderFrame.

The time between ospCancel and return of ospWait cannot be used for that, because a commit may change datastructures which are still access by a render task (until that one checks the cancel-flag), which would result in a crash.

Thanks for the info. I seem to remember that setting a data object as parameter, without the data having been committed can cause problems, even if the object on which the parameter is being set isn't committed. Is that still the case? I.e. should data objects be treated specially, or can they simply be treated the same when it comes to deferred commits (as long as the order of deferred commits is correct)? And I guess that a shared data object cannot be altered during rendering, regardless of using a deferred commit?

Looking at that example, won't certain window events, like a reshape, trigger updates on the camera and subsequent commit() while rendering is active?

From the manual:

The use of either ospRenderFrame or ospRenderFrameBlocking requires that all objects in the scene being rendered have been committed before rendering occurs.

I guess I'm a bit unclear to what extent "all objects in the scene" applies? Only those directly set on the World, or also all objects reachable from those, like a transfer function, or data object. Are there any general guidelines for this? For example, looking at the ospray_testing builders, like GravitySpheres, it seems they don't commit any of the data objects, plus they do fully set up a world and return it. Yet in GLFWOSPRayWindow::refreshScene() the world is updated using a builder and committed, while the renderer is also updated but then added to the list of objects to commit.

Hmmm, seems there's more undocumented constraints in handling commits, e.g. #437

Unfortunately, commiting the World is indeed currently necessary if an Instance/Geometry/Volume changed (spatially).

Unfortunately, commiting the World is indeed currently necessary if an Instance/Geometry/Volume changed (spatially).

Related to this restriction, does the same hold for lights? Or is a world commit not needed if only parameters of lights are changed? Changing the world light list obviously would force a commit.