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
> vsgbuilder -i data/textures/lz.rgb
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
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.