Instanced Animation


photo

Recommended Posts

Dear @tower120,

UNIGINE has support for skinned meshes and Instance_ID using UUSL.

IMO it is possible to do it exact way like explained it in the above approach at http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/SkinnedInstancing/doc/SkinnedInstancingWhitePaper.pdf

and there is another  approach with Pure Mesh vertex animation and not the skinned animations as described here

But in both approaches considerable work is required to achieve results. And most important task of Baking animation data to the textures.

1. With first approach bone animation frames.

2. With second approach limited animation frames for vertex pose.

All the best.

Rohit

Link to post

@rohit.gonsalves Thanks I didn't heard about second approach.

So in either way I should implement it myself.

But how I should call glDrawArraysInstanced ? Is there some kind of RHI(Rendering Hardware Interface) in Unigine for that?

---------

And I don't see UUSL's "Instance_ID" parameter described anywhere...

EDIT: I see "IN_INSTANCE" now.

Edited by tower120
Link to post

Dear @tower120,

It is possible to do that but I am afraid in Community edition.

As getting DirectX device and Context or OpenGL context is not present in Community edition. 

@silent Is there any other way to achieve it?

Regards,

Rohit

 

Link to post

Yeah, access to the OpenGL / DirectX context is possible only with CustomApp (which is available starting from Engineering edition).

Maybe the situation will change in the future, but right there is no option to do that.

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post

And what about Cluster? Doesn't it do instancing? Or it merge mesh?

If there any way to do instancing with built in tools - I'm good. I just need to know instance_id of each object, to pack texture for it...

Link to post

Instancing out of the box works only for the fully identical objects (including the UV, material/shader parameters, mesh file). So if you have like 4 different people in a crowd you need to create 4 different clusters.

By default ObjectMeshSkinned is already using the instancing (you can check the UnigineScript sample stress/skinned_01 with 2400 moving skinned objects). You can further improve FPS there by reducing the update FPS via logic for the objects that is far away from camera (or completely invisible).

 

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post

> Instancing out of the box works only for the fully identical objects (including the UV, material/shader parameters, mesh file).

But that's not that you can instance 4 different meshes with 4 different shader programs in one drawcall in opengl. Or you can?

 

> So if you have like 4 different people in a crowd you need to create 4 different clusters.

That's ok. Is it guaranteed that shader's "instance_id" will be same as it's index in ObjectMeshCluster::createMesh(...) array?

Link to post

> By default ObjectMeshSkinned is already using the instancing (you can check the UnigineScript sample stress/skinned_01 with 2400 moving skinned objects). You can further improve FPS there by reducing the update FPS via logic for the objects that is far away from camera (or completely invisible).

I found stress/skinned_01.cpp - is there a way to run it? I don't see it Unigine SDK browser...

And what happened if I start animation not simultaneously (with fluctuation in 0.25-2sec)? It still be instanced?

Link to post
Quote

I found stress/skinned_01.cpp - is there a way to run it? I don't see it Unigine SDK browser...

Just run any UnigineScript sample and move to upper level via [../] button:

image.png

After that you can see all the samples categories (including the stress one).

Quote

But that's not that you can instance 4 different meshes with 4 different shader programs in one drawcall in opengl. Or you can?

That's not possible because of the different shader.

 

Quote

 Is it guaranteed that shader's "instance_id" will be same as it's index in ObjectMeshCluster::createMesh(...) array?

Unfortunately no. Sometimes it's required more than a single draw call to draw all the instanced objects, so instance id may vary.

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post

Regarding the instanced animations - It looks like I was wrong, sorry for the misleading info.

There is no instanced skinned meshes rendering, but animations re-use across different objects. So, in theory if your animation playtime will be the same for the set of multiple skinned objects it would be slightly faster in rendering, that's it.

Anyway, I would recommend to play with already existing objects and optimization techniques and if they don't fit your needs - start develop some custom solution that will handle your use-case better.

Thanks!

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post

>> Unfortunately no. Sometimes it's required more than a single draw call to draw all the instanced objects, so instance id may vary.

Is there something I can do about it? I need to know to which object belongs vertex. Or even better - have per instance data in shader, like using glVertexAttribDivisor. And I didn't try personally, but according to doc Unity have support of per-instance data https://docs.unity3d.com/Manual/GPUInstancing.html

 

>> Anyway, I would recommend to play with already existing objects and optimization techniques and if they don't fit your needs - start develop some custom solution that will handle your use-case better.

Unfortunately, looks like ObjectMeshSkinned as-is will not work for us.

Looks like cluster is the only way to have instanced redndering....

Link to post

There is no support for per-instance data in the shaders, I'm afraid.

However, it may be added in the future versions of the SDK (can't give you an exact ETA right now, sorry).

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post

That would be great!

And if I may suggest, you probably need to mention that "cluster" is for GPU instancing... That not mentioned in the docs... I'm still guessing is there some fallback scheme where it just melds all meshes into one... And is it safe to update object positions on per-frame basis...

Edited by tower120
Link to post

You can check CPUShader sample in SDK Browser -> Samples -> C++ API -> CPUShaderthat shows how to update 240k objects inside different ObjectMeshClusters.

Maybe that would be useful in your case.

Quote

 I'm still guessing is there some fallback scheme where it just melds all meshes into one

What do you mean by that?

Thanks!

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post

Here is an example of simple cubes that draws in a 1 DIP:

image.png

White cube - 1 DIP, pink cube - 1 DIP, 1 DIP for lightning and 5 DIPS for srgb correction and other composite stuff - 8 in total).

 

Adding more cubes will not result in DIPs increase since engine is automatically batch the identical objects (same .mesh and shader parameters):

image.png

Engine automatically batches up to 341 similar objects if DX11 is being used. OpenGL is limited to 42 objects per batch.

No need to merge all the stuff into a single mesh to save the GPU performance. Most of the applications are actually more CPU bound and ObjectMeshCluster is designed to reduce the CPU workload. It starting to kick in when you need to render a really huge amount of the objects (50k+).

Maybe that will help a bit :)

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post

> You can check CPUShader sample in SDK Browser -> Samples -> C++ API -> CPUShader that shows how to update 240k objects inside different ObjectMeshClusters.

Yes I saw it. It does work with moving objects. If there would a way to put vertex animation there - that would work for us.

-----

Quote

 I'm still guessing is there some fallback scheme where it just melds all meshes into one

What do you mean by that?

I mean that frankly speaking no one says it will use GPU instancing. It could bake "cluster" in one single mesh - and draw it. Same 1 dip :).

Documentation does not says how exactly things happen.

Edited by tower120
Link to post
Quote

 Yes I saw it. It does work with moving objects. If there would a way to put vertex animation there - that would work for us.

I'm afraid this is not possible.

For such custom task maybe using a MeshDynamic will be a better idea. Some experiments would need for sure to understand how it goes :)

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post
2 hours ago, silent said:
Quote

 Yes I saw it. It does work with moving objects. If there would a way to put vertex animation there - that would work for us.

I'm afraid this is not possible.

I meant vertex shader animation. Offset vertices in shader. If I would need to animate all meshes exactly the same, that would be already doable.

-----

Previously, you said

22 hours ago, silent said:

Sometimes it's required more than a single draw call to draw all the instanced objects, so instance id may vary.

What if I will not use transparent materials and cluster will contain fixed number of objects below some threshold (you said thats 42 object for OpenGL)?

Could that work?

Link to post
  • 4 weeks later...

@tower120,

Did you implement the this specific behavior of the thread topic?

Rohit

Link to post
5 hours ago, rohit.gonsalves said:

@tower120,

Did you implement the this specific behavior of the thread topic?

Rohit

It is impossible to implement such behavior in UNIGINE. We need per-instance data in shader for that. Either instanced skeletal animation done by engine (not sure if that can be done in generic way).

That was a deal-breaker for us... And despite the fact how much I "love" Unreal Engine, it have what we need...

I just hope that UNIGINE will get per-instance custom data before we finish our proof-of-concept prototype.... Maybe we could change engine before we start "actual" work.

Link to post

Dear @tower120,

One of our probable client needs 5000-10000 crowd simulation with behaviors.  UNREAL has such mechanism where it bakes animation data. 

We have implemented 12 diff Mixamo animations with 10 character meshes. We can able to push  450 characters only. Apart from GPU,  data push is the blocker. I agree if such auto instanced mechanism exists, it will help to simulate crowd.

I will try to map Golaem Crowd to Unigine for this.  Lets see, fingers Crossed.

Please connect and PM. I am ready for co-development. 

Regards,

Rohit

  • Like 1
Link to post
Posted (edited)

UNREAL have no built-in mechanism for instanced animations.

But it have custom per-instance data. And it is also possible to pass additional data to vertex shader (like VBO attribute) [thought that's hard - we just use float4 'color' attribute for our cause]

That's enough to implement instanced animation on your own in UNREAL.

Edited by tower120
Link to post

Yes. You are right. It was through a plug-in.

Rohit

Link to post

Hi @rohit.gonsalves

I will be interested as well in a crowd rendering pipeline. I am currently trying to port an animation baking/instancing shader from Unity to Unigine. Please tell me if you are interested so we can share source code as well.

Cheers

  • Like 1
Link to post