Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-level instancing? #304

Open
paulmelis opened this issue Mar 5, 2019 · 3 comments
Open

Multi-level instancing? #304

paulmelis opened this issue Mar 5, 2019 · 3 comments

Comments

@paulmelis
Copy link

I'm trying to debug some code that is not showing any geometry in the rendered output, so I wanted to verify if what I'm doing is actually supported when it comes to instancing. See the code below, should the multiple levels of wrapping an ospGeometry into an ospModel followed by instancing, i.e. base -> container -> world, actually work? Or is it limited to two levels?

// Create base object

OSPGeometry mesh_geometry = ospNewGeometry("triangles");
    // ... set mesh data
ospCommit(mesh_geometry);

OSPModel mesh_model = ospNewModel();
    ospAddGeometry(mesh_model, mesh_geometry);
ospCommit(mesh_model);

// Instantiate many objects

OSPModel container = ospNewModel();

OSPGeometry     instance;
osp::affine3f   xform;

for (int i = 0; i < N; i++)
{
    // read tx, ty, tz, rx, ry, rz from file, compute M based on these values
    M = ...

    xform.l.vx.x = M[0];
    xform.l.vx.y = M[1];
    xform.l.vx.z = M[2];

    xform.l.vy.x = M[4];
    xform.l.vy.y = M[5];
    xform.l.vy.z = M[6];

    xform.l.vz.x = M[8];
    xform.l.vz.y = M[9];
    xform.l.vz.z = M[10];

    xform.p = { tx, ty, tz };

    instance = ospNewInstance(mesh_model, xform);
    
    ospAddGeometry(container, instance);
}

// Add container to scene, as instance

OSPRenderer renderer = renderer = ospNewRenderer("scivis");

OSPModel world = ospNewModel();

OSPGeometry instance = ospNewInstance(container, xform);    
ospAddGeometry(world, instance);    
ospRelease(instance);

ospCommit(world);
ospSetObject(renderer, "model",  world);
ospCommit(renderer);
@jeffamstutz
Copy link
Contributor

Hi,

Only single-level instancing is supported in OSPRay. In OSPRay v2.0+, we intend on making this explicit in the API by having OSPGeometry-->OSPGeometryInstance-->OSPWorld, where OSPWorld replaces OSPModel. This will directly express the single-level instancing constraint in the API, but allow us to introduce multi-level instancing later if we can do so with a satisfactory design (i.e. introduce recursively defined OSPInstanceGroup).

The biggest issue we face with multi-level instancing is the meta-data around what instances represent in the scene (i.e. overriding attributes such as material lists). Our scene graph which we implement on top of OSPRay does support multi-level instancing, but it is yet-to-be documented...

The solution for OSPRay v1.x is to flatten all instances into a single OSPModel, where each OSPModel that is instanced represents the smallest group of geometries to be instanced.

Cheers,
Jeff

@paulmelis
Copy link
Author

Dang, so my hunch was right 😞

The section of the docs under Model is then a bit too general as it claims, without mentioning the one-level limit

Models are a container of scene data. They can hold the different geometries and volumes as well as references to (and instances of) other models.

@johguenther
Copy link
Contributor

Well, the truth is somewhere in-between "supporting" and "not supporting" multi-level instancing. The original goal (as written in the documentation) was to support it, but the current implementation has several limitations and hacks (so we opted for a clean cut in OSPRay v2). For "simple" materials and multi-level instances of "basic" geometries it should work. More complex setups (nested material lists, geometry lights) will likely be broken.

I just tried myself, it worked. Be sure to commit each instance / model / geometry, otherwise a zero-only transformation matrix will be used (and the instances just vanish); i.e. call ospCommit(instance); in the loop before adding it to the container and also before adding the container to the world. (BTW: in OSPRay v2 we also like to relax these commit constraints, commits are so easy to forget)

paulmelis pushed a commit to surf-visualization/blospray that referenced this issue May 19, 2019
(see RenderKit/ospray#304), so we need to
work around that. Changed the geometry plugin load function to return
a list of (OSPModel, xform) pairs, which will get instanced in the
top-level "world" OSPModel.

There is still a bug in that the transform applied to the Blender object
is not applied to the instanced geometry.

Unrelated tweaks to code that updates bbox mesh during export, to see
if this fixes a segfault.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants