New vsg::Builder class for creating primitive shape geometries

302 views
Skip to first unread message

Robert Osfield

unread,
Aug 9, 2021, 9:41:54 AM8/9/21
to vsg-users : VulkanSceneGraph Developer Discussion Group

Hi All,

I have just merged with VulkanSceneGraph master in vsg::Builder class to provides a convenient way of creating shape primitive geometries that can be added to the scene graph.

The changes are:


vsg::Builder class can create a single box, cone, cylinder, capsule, quad and sphere geometries as well as instance them at specified positions and colours.  The dimensions and orientations, texture image, and instance information is provided by a vsg::GeometryInfo struct that is passed to the create methods in the form:

    auto builder = vsg::Builder::create();
    vsg::GeometryInfo info; // defaults to base size of 1,1,1 at position 0,0,0
    auto node = builder->createSphere(info);

I have created a vsgbuilder example that illustrates it's use.  The example is:


> vsgbuilder

builder_white.png

> vsgbuilder -i data/textures/lz.rgb

builder_texture.png
I'm not yet happy with the way the sphere, cylinder, cone and capsule are textured so plan to tweak the texture coordinate generation so the image is draped over the geometry without any repeats. 

By assigning a vsg::vec3Array of coordinate positions, and vsg::vec4Array of colours to the vsg::GeometryInfo you can enable hardware instancing. To illustrate the you can run the vsgbuilder example with the number of instances you want, the type of shape, and the example will create a set of random positioned and coloured shapes:

 > vsgbuilder --sphere -n 10000

10000_spheres.png

When running vsgbuilder with the -t option to enable a small window test (small to avoid fillrate limit) this scene renders at 1029fps on my Geforce 2060.  Each sphere is currently rendered with 200 vertices, so that maps to roughly 2Bn vertices a sec. 

If I up that number to a 1,000,000 spheres, performance drops to 13.2fps, for around 2.6Bn vertices/sec.

If I do the same test with boxes (-f constrains us to rendering specified number of frames.) :

> vsgbuilder --box -n 1000000 -t -f 1000

I see 195fps, which is 4.68Bn vertices per second.

With modern NVidia cards there is support for Mesh Shaders, which could allow us to do GPU culling and Level of Detail all with the mesh shaders, something that could significantly improve performance.  I will leave this work to a later date as I still have other features I'd like to implement first.

The feature I'll be implementing next is enabling dynamic updates of the instance positions and changes to the number of instances so we can handle dynamic datasets. This will provide a good base for handling datasets like like live LIDAR rendering.

I also want to add control of the tessellation level of the cones, sphere's, cylinders and capsules so we can trade performance for visual quality.  Potentially one could LOD different resolutions versions.

Billboarding, either around a point or an axis would make it straight forward to do point sprints and billboard effects like trees. 

I would also like to generalizing the instance positions so we can pass 4x3 or 4x4 matrices to place the instances.

--

For this work I've used the vsgXchange assimp shaders as a base.  Longer term my plan is build upon these shaders and make them flexible and feature rich - adding support for controlling lights, shadows, texture projection.  Then change the vsgXchange OSG and Assimp loaders to use this same set of shaders so they all build share the same shaders and uniforms and attributes to control positions.

Introducing instancing also brings in the issue of how CPU based scene graph codes handle that fact that the final vertices positions aren't just controlled by the model matrix and vertex positions.  I'll need to come up with a callback scheme to enable user and the even the vsg::Builder codes to set the appropriate callback to specify how to transform the vertices correctly. 

This functionality is crucial for support of computing bounds and intersections.

As you'll have seen by all the additional stuff I have plans for, the present vsg::Builder is stepping stone that provides some useful functionality now, but there is plenty of related work that will follow along.

Cheers,
Robert.

Robert Osfield

unread,
Aug 10, 2021, 12:18:07 PM8/10/21
to vsg-users : VulkanSceneGraph Developer Discussion Group
Today I took a bit of detour from the vsg::Builder work to look at how to best implement dynamic updates of vertex and index array data associated with vsg::VertexIndexDraw/vsg::Geometry/vsg::BindVertexBuffers/BindIndexBuffer.  In order to do dynamic updates of the instance positions that vsg::Builder we need to update the array data, but rather than come up with a very specific solution for the subgraph created by vsg::Builder I've decided to try and make it generally easier to update vertex data.

The approach I've decided to try first is to refactor vsg::BufferInfo and vsg::ImageInfo so they created on the heap like other scene graph objects, and to make these info objects more publicly accessible so you can more directly specify what data on the CPU is updated and how it maps to associated GPU buffers.  So far I have only made the change to vsg::BufferInfo and it's already required lots of changes to internals of the VSG - 32 files and 300 lines changed!

Next up I'll change vsg::ImageInfo to be similar to vsg::BufferInfo has been changed so that both are subclassed from vsg::Inherit<Object,..>.  Then I'll change the public interface to various classes so that they can take a BufferInfo or ImageInfo object rather than just have public interface to vsg::Data.  I don't know how intrusive this change might be yet.... So it's all being done in a BufferInfo branch of VulkanSceneGraph and vsgExamples.

Changes to VSG so far:

Changes to vsgExamples to keep things building:


Robert Osfield

unread,
Aug 10, 2021, 1:40:37 PM8/10/21
to vsg-users : VulkanSceneGraph Developer Discussion Group
I have now updated vsg::ImageInfo to subclass from vsg::Inherit<> in the same way to the changes to BufferInfo that I've checked in earlier.

Updates to VSG:

Updates to vsgExamples
   https://github.com/vsg-dev/vsgExamples/commit/730372b61d94f9260e24a7535d76a9af3202c376

Next up I'll adapt the public interfaces of a few of the scene graph level nodes/state objects to leverage these changes, my hope is we'll end up with a more flexible public interface.

Robert Osfield

unread,
Aug 26, 2021, 12:37:28 PM8/26/21
to vsg-users : VulkanSceneGraph Developer Discussion Group
I've add quite a bit more functionality to vsg::Builder since my last post.  It now can create boxes, quads, disks, spheres, cones, capsules and heightfields, as well as options for apply textures and displacement maps, and wireframe and flat shaded shaders.

To test out the dynamic update of textures and displacement maps at runtime I've rewritten the vsgdynamictexture example to use vsg::Builder rather than create it's own local scene graph, much less code required now and much more functionality!   These are the changes changes to vsgdynamictexture, 48 lines added, 99 removed!

The latest changes can be found in the Builder branch of the VulkanSceneGraph, and Builder branch of vsgExamples.

I've uploaded a video to youtube to illustrate it in action. The video shoes a 256x256 displacement map texture being updated on the CPU then transferred each frame to the GPU, with the vertex shader offsetting the height of input mesh (a flat regular mesh in this case) to it's final displaced position with the normal computed in the vertex shader as well.

Reply all
Reply to author
Forward
0 new messages