Making geometry available for IPR rendering



  • Our plugins have two generator objects that both produce two vastly different representations for editor display and for rendering. We decide which one to create by the existence of BUILDFLAGS::INTERNALRENDER/BUILDFLAGS::EXTERNALRENDER. That produces problems with all sorts of IPR renderers, because they use the editor representation. However, I noticed, that this is being solved somehow. For example, when using Multi-Instances and setting them to display boxes in the viewport, most IPR renderers (I tried Arnold and heard it works in Redshift as well) do show the render geometry. Same appears to work happen (at least in Arnold) with the Subdiv object. The editor shows the editor detail, in the IPR I get the render subdivision.

    I am not sure how this happens (or whether both of the above cases use the same mechanism), but I would like to figure out how this works, so we can do the same.

    I am aware, that we could just create both, editor and render geometry always and just set the visibility flags in the cache. However, at least with one of our objects that would be less than ideal, because generating the full detail representation also takes a bit.

    Hope someone can help, ideally with some insight on how the two examples, I described above, work.

    Best
    Timm



  • @tdapper said in Making geometry available for IPR rendering:

    Anyway, the way we thought about it was to use the function publishing interface and implement a call on our object,

    Hi Tim, it sounds like an option more flexible but also more time consuming, but this means that, in any case, the renderer vendor - and consequently - even Maxon should be notified about your APIs ( I think this is what you mean by function publishing interface) and implement specific code to threat your geometries. If there are more arguments than the initial one (which still can be still solved by using the messaging approach) to require to implement and maintain an API then go for it otherwise I would consider a different approach.

    Cheers, R



  • Hi Tim, thanks for reaching out to us.

    I see your point but I think the cases you've reported might not be fully representative: for the Multi-instances, external renderers usually implements an in-rendering instancing mechanism so the fact that the viewport represent a bounding-box and the IPR shows the right instanced geometry as expected.
    At the same time, I think Arnold shows up subdivided geometry in IPR, not because it's retrieving a different (more-detailed) representation than the one shown in the viewport, but rather because it generates on-the-fly in-rendering subdivided geometry once it finds a geometry child of a subdiv modifier.

    Given the cases you mentioned, I think they are all managed on the rendering-engine/-integration side but what you could think of is about implementing a mechanism similar to what offered in R23 to grant 3rd-party renderers accessing scene-nodes cached geometry.
    The idea is easy: you inform all the rendering vendors you deem relevant to your customers about a message(s) your ObjectData is listening to that could trigger your generator to return back different LOD geometry (or geometries) based on the message fired. This could give them the chance to retrieve your high-level detail cache also in IPR.

    Cheers, R



  • Hi Ricardo,

    Thanks for helping me out here. Couple followup questions:

    1. We actually have been thinking about offering a mechanism for rendering vendors to retrieve the full geometry, my observations just made me think that there might be a better way (meaning: a standard way that wouldn't have to be vendor specific). Anyway, the way we thought about it was to use the function publishing interface and implement a call on our object, similarly to what the Hair module does. What would be your reasoning to prefer using messages instead?
    2. Another approach we thought about was dropping the full geometry into the cache always, and allowing a different editor representation not by using the BUILDFLAGS::INTERNALRENDER/BUILDFLAGS::EXTERNALRENDER flags in GetVirtualObjects(), but by overwriting the Draw() method and just drawing different viewport geometry ourselves (e.g. by building one or more PolygonObject's and drawing them using ObjectData::DrawPolygonObject(). Do you have any thoughts on this? Will this come with a performance penalty, or is that basically what is done internally?

    Thanks for your awesome support, @r_gigante!

    Best
    Timm



  • Hi Tim, sorry for getting late here.

    I've explored a little bit more your topic and the solution that I would encourage you to explore is something which stems from your second option.

    The idea of drawing something in viewport via BaseDraw::DrawPolygonObject() is, first, pretty straight-forward and, second, performance penalty-free. The first attempt was to override the ObjectData::Draw() method but when it came to hide the representation of the cache generated in the ObjectData::GetVirtualObject() using SetNBit() it caused also the DRAWPASS::OBJECT not to be executed anymore in the overridden Draw() method with the consequence of not being possible to show the low-res mesh in the viewport and hide the high-res for rendering purposes at the same time.
    Given that I had to consider to split the viewport visualisation and the object cache generation using respectively a SceneHookData and an ObjectData. in this case overriding the SceneHookData::Draw() method is was capable to draw in viewport the low-res version and feed rendering engines (either in IPR or offline mode) with the desired cache (below plane is the "low-res" object, sphere is the "high-res" one).

    13584f18-01e7-43aa-b5ca-5c0b1fda8819-image.png

    Unfortunately the solutions was indeed better but far form being perfect. This come by the fact that some of our cloners (MoGraph Cloner to name one) when representing in scene the cloned elements looks for the cache of the nested object and completely discard what I've forced with the SceneHookData::Draw() to represent in viewport (which is reasonable). This is something that, at the moment, can't be prevented though.

    fcc7888f-eea1-4a69-8665-d2dea6784985-image.png

    Cheers, R



  • Hi @r_gigante!

    Thanks for the elaborate answer, there is a lot to chew on here. I was wondering if you also had an answer to my first question:

    @tdapper said in Making geometry available for IPR rendering:

    We actually have been thinking about offering a mechanism for rendering vendors to retrieve the full geometry, my observations just made me think that there might be a better way (meaning: a standard way that wouldn't have to be vendor specific). Anyway, the way we thought about it was to use the function publishing interface and implement a call on our object, similarly to what the Hair module does. What would be your reasoning to prefer using messages instead?

    Best
    Timm



  • @tdapper said in Making geometry available for IPR rendering:

    Anyway, the way we thought about it was to use the function publishing interface and implement a call on our object,

    Hi Tim, it sounds like an option more flexible but also more time consuming, but this means that, in any case, the renderer vendor - and consequently - even Maxon should be notified about your APIs ( I think this is what you mean by function publishing interface) and implement specific code to threat your geometries. If there are more arguments than the initial one (which still can be still solved by using the messaging approach) to require to implement and maintain an API then go for it otherwise I would consider a different approach.

    Cheers, R



  • Hi,

    without further feedback, we will consider this thread as solved by tomorrow and flag it accordingly.

    Cheers,
    Ferdinand


Log in to reply