An example of a good design of a node structure of a Vulkan Scene Graph #1190
-
Hello, From what I understand, Vulkan scene graphs provide a declarative way to describe how to render a scene including the commands as scene nodes, which is a great idea. However, I am struggling with how to combine these node types (cull, switch, LOD, groups, transforms, etc.) effectively. I was wondering if there are any good examples that illustrate how these nodes can be combined in a well-organized manner in a real project? I want to avoid locking myself into a bad design with a poorly structured scene graph. VSG, like Vulkan, is very flexible compared to old scene graphs, but for someone lacking experience like myself, it can lead to bad designs similar to the outdated hierarchical transforms, drawing, and culling lock from 15 years ago. Thank you! |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
In some ways the VulkanSceneGraph is much like scene graphs that came before it - the scene graph hierarchy provides the capability to cull subgraphs using culling nodes - like vsg::CullNode/CullGroup/LOD/PagedLOD, and to manage logical structure with vsg::Group/vsg::Swtch, scene graph transforms with vsg::Transform/MatrxiTransform/AbsoluteTransform though to state StateGroup the various StateCommand through to rendering leaves like vsg::Geometry/VertexIndexDraw. Principles used in prior scene graph that worked well for performance and easy of scene management that works with prior scene graphs also carry over to the VSG - well balanced scene graphs, with attention paid to effective culling and batching of draw data. Areas were things diverge are where the VSG provides things that prior scene graph don't, and this is largely down to Vulkan providing new capabilities like compute, ray tracing and mesh shaders, being able to record and render in multiple thread. The threading side is not just on the CPU side but on the GPU side as well, so there are various synchronization features/topics that need to be understood once you start doing more sophisticated rendering. There are also consequences from the VSG and Vulkan having lower CPU overheads than scene graphs like the OSG and API's like OpenGL. Previously coarse grained batching was required to get good performance form OSG/OpenGL, that isn't required to the same degree, and perhaps not at all. This performance headroom can mean you can simplify your application be being able to handle data in a way that is convenient to your task rather than working around the performance constraints of the underlying technology. What I have said is very open ended. At this point I can't provide any specific suggestions as I don't know anything about what type of application, what types of scenes you'll be wanting to tackle, nor your level of understanding of the various topics required. Could you give us an overview of what you are trying to achieve, what APIs & approaches you've used in the past and then the community can have a go at making suggestions about approaches to take and what resources that might already be available to help you learn how best to tackle your application. |
Beta Was this translation helpful? Give feedback.
-
Thank you very much for your quick and prompt response. I apologize for the delay. I am prototyping an isometric strategy game with tens of thousands of small objects. There aren't many buildings, but there are thousands of units (which may be implemented as billboards). So the game is basically highly dynamic and it is not have defined scenes. Objects will be created and deleted based on the situation in the game. After reading your reply, I revisited my old books on OSG, and I found it very similar to VSG. I think I can learn more about the patterns used in OSG and apply what I can to VSG. Is recreating the scene graph for dynamic things every frame feasible? Or something like object pooling with hiding/showing is better? Thank you |
Beta Was this translation helpful? Give feedback.
-
In general creating and destroying objects is relatively expensive on the CPU and especially the GPU so pre-allocating resources and then reassigning values at runtime to introduce the dynamic aspect will generally perform best. With modern GPUs you can do a lot of the work on the GPU, billboards a good example of this. You could pass position, sizes and material properties in via per vertex and per instance arrays, or uniform arrays or textures or a combination of all of these. Such approaches allow you to scale into hundreds of millions of billboards at real-time frame-rate on modern hardware. Something you may also want to consider is making the scene graph implementation mirror you game datastrctures, or possibly even share the game data structures. For instance if you game objects that you want to render have a position in the world and other properties that are used in rendering you could pack these into a uniform array stored in a vsg::Array and then share the same layout on the CPU and GPU. You'd need to take care with the layout of GameObjectStruct so that it can be shared, but this needn't be a great burden. The vsg::PbrMaterial and PhongMaterial structs are examples of how one can pack data that is then pass as a vsg::Value or vsg::Array to the GPU. |
Beta Was this translation helpful? Give feedback.
In some ways the VulkanSceneGraph is much like scene graphs that came before it - the scene graph hierarchy provides the capability to cull subgraphs using culling nodes - like vsg::CullNode/CullGroup/LOD/PagedLOD, and to manage logical structure with vsg::Group/vsg::Swtch, scene graph transforms with vsg::Transform/MatrxiTransform/AbsoluteTransform though to state StateGroup the various StateCommand through to rendering leaves like vsg::Geometry/VertexIndexDraw.
Principles used in prior scene graph that worked well for performance and easy of scene management that works with prior scene graphs also carry over to the VSG - well balanced scene graphs, with attention paid to effective culli…