I use SceneCustomObjects all the time. Why?
tl;dr: It's to get easy access to a render block. I must have easy access to a render block.
But to explain futher, there's a lot of data that I build using compute shaders.
Within a single render override, I'll often dispatch many compute shaders in series, and it's common that one compute shader will depend on the output of another.
To organize things, I've created a system of "render jobs" that can be created at any time and execute in the render override of a SceneCustomObject managed by a GameObjectSystem.
For example, this is how I'm using three different compute shaders to implement an isosurface extraction job that creates a mesh using SDF primitives:
- Given a buffer of SDF primitives and the dimensions and resolution of a voxel grid, a compute shader outputs between zero and one vertices per voxel using the surface nets algorithm.
- I check the hidden counter of the output buffer to see how many vertices were output. A second compute triangulates the vertices, outputting between 0 and 18 indices per vertex.
- Because the normals estimated while running the surface nets algorithm look terrible, I use another compute shader that takes the vertices and indices of the mesh and recalculates the normals in three subsequent dispatches:
- For each vertex, the a temporary buffer of vertex normals is set to zero.
- For each triangle, the triangle normals is added to that triangle's vertex normals in an atomic way.
- For each vertex, the accumulated temporary normals are normalized and added to the actual vertex buffer.
There are a three reasons I still need a render block to do this:
First, I need to be able to use ResourceBarrierTransition to prevent race conditions, and to ensure that hidden counter values are available when I try to read them back during the job.
Second, the number of threads dispatched by one compute shader depends on hidden counter values of compute shaders dispatched previously in the same frame.
Third, because it makes no sense to a dispatch a compute shader when the prerequisites for it to run correctly aren't met (e.g. the first compute shader didn't output any vertices at all), there are times when the render job needs to be cancelled before everything completes.
The easiest way to make me not feel the need to use SceneObjects is to make it easy to get a render block.
For example:
- Add an OnRender virtual function to GameObject that always executes in a render block.
- Add rendering stages for GameObjectSystems to listen to.
And that would pretty much make everything way easier for me.