Discussion:
[Opensg-users] OpenSG2: Cluster shading example
Johannes Brunen
2017-05-12 07:43:03 UTC
Permalink
Hello,

As promised, today I send you my finished and polished ClusterShading example. It is based on:

Ola Olsson et.al
http://www.cse.chalmers.se/~uffe/clustered_shading_preprint.pdf
High Performance Graphics (2012), pp. 1-10
C. Dachsbacher, J. Munkberg, and J. Pantaleoni (Editors)

This invention describes the clustering the view frustum and population of these clusters by lights contributing to the shading of the cluster's fragments. Light lists are generated for each cluster and evaluated in the fragment shader.

Additionally I have used the

SIGGRAPH 2015 course "Real-Time Many-Light Management and Shadows with Clustered Shading"
https://newq.net/publications/more/s2015-many-lights-course

I have implemented the example in a classic forward rendering setup and hope that it makes its way into OpenSG and that is useful for anyone.

Additionally, the patch contains small enhancements to the MultiLightChunk and corrections to the examples basing on this chunk.

@Carsten: The patch does also contain the MultiPropertyUBOChunk and MultiPropertySSBOChunk classes which I have forgotten to add to my recent patch ' ssbo_ubo_opensg.patch'. There, I did introduced common base classes for the various UBO and SSBO classes, and I adapted these two missing guys also.

Best,
Johannes
Johannes
2017-05-30 12:27:18 UTC
Permalink
Hello Carsten,

I have finished the 'ClusterShadingStage' as promised. I have written an
example 'multirangelightclustershadingstage.cpp' which is basically
identical to the 'multirangelightclustershading.cpp' example but uses
the new Stage core instead of setting up the technique by hand.

Since the 'ClusterShadingStage' depends on the 'Contrib/ComputeBase'
library and because I think that this 'Stage' does not belong into this
box, I have introduced a new 'Contrib' library named 'Techniques' for
high level components that depends on 'Contrib/ComputeBase'.

I have attached a zipped patch file 'cluster_stage_opensg.azip' and I
will send it also directly to you so that is get not lost.

Because of the 200k limit of the mailing list, I have to store the patch
somewhere else. I have uploaded it to File-Upload.net and you
can download it from

https://www.file-upload.net/download-12525698/cluster_stage_opensg.azip.html

All missing parts are included in this patch aside from the
'props_opensg.patch'. For the 'props_opensg.patch' I did have had some
questions and asked for help. Unfortunately I got no answer.

The current patch file also contains some additions to the
infrastructure, i.e. extension to 'MatrixUtility', correction to
'AlgorithmComputeElement', extension of 'Image', a new 'SimpleCurve', a
new 'SimpleLightGeometry'. All needed for the stage and the example but
nothing fancy about these.

Additionally, the patch also contains the pending
'MultiPropertyUBOChunk' and 'MultiPropertySSBOChunk' changes that were
missing in the [c9024f] commit.

Last but not least it contains an enhancement to the 'MultiLightChunk'
with respect to usability and a new twist parameter for the cinema light
source.

The usage of the 'ClusterShadingStage' core is quite simple. It belongs
into a parent node of the scene that would like to take credit from its
offerings. A 'MultiLight' chunk must be created and provided to the
'ClusterShadingStage' core. The scene is expected to use shader
programs. The fragment shader code must be expanded by the shader code
provided by a call to function 'getFragmentProgramSnippet()' of the
stage (*). This fills all the necessary parts into the fragment shader
code. In the fragment shader the normal light shading calculation takes
place. The only difference is that the light is determined from the
global list of lights with the help of the light grid and light index
list provided by the 'ClusterShadingStage'. buffer and texture binding
points and all buffer block names can be adapted by the stage API if
necessary.

So basically the c++ code and fragment shader code would look like this:

cluster_shading_stage = OSG::ClusterShadingStage::create();
cluster_shading_stage->setMultiLightChunk(multi_light_chunk);
cluster_shading_node->setCore(cluster_shading_stage);
cluster_shading_stage->setLightBindingPnt(1);
... binding points for all of the buffers and textures used

stringstream ost;
ost
<< "#version 440 compatibility"
<< "..."
<< cluster_shading_stage->getFragmentProgramSnippet()
<< "..."
<< "vec3 directionalLight(uint light_index, ...) {..."
<< "vec3 pointLight(uint light_index, ...) {..."
<< "vec3 spotLight(uint light_index, ...) {..."
<< "vec3 cinemaLight(uint light_index, ...) {..."
<< "..."
<< "void main()"
<< "{"
<< " ..."
<< " vec3 color = vec3(0,0,0);"
<< ""
<< " uint list_idx = 0;"
<< " uint light_count = 0;"
<< ""
<< " if (clusteringData.enabled)"
<< " {"
<< " uvec2 grid_data = getGridData("
<< " gl_FragCoord.xy"
<< " vPositionES.z);"
<< ""
<< " list_idx = grid_data.x;"
<< " light_count = grid_data.y;"
<< " }"
<< " else"
<< " {"
<< " light_count = affectedLightIndexList.idx.length();"
<< " }"
<< ""
<< " for (uint i = 0; i < light_count; ++i)"
<< " {"
<< " uint light_idx = (clusteringData.enabled)"
<< " ? lightIndexList.idx[list_idx+i]"
<< " : affectedLightIndexList.idx[i];"
<< ""
<< " switch (lights.light[light_idx].type)"
<< " {"
<< " case POINT_LIGHT:"
<< " color += pointLight(light_idx, ...);"
<< " break;"
<< " case DIRECTIONAL_LIGHT:"
<< " color += directionalLight(light_idx, ...);"
<< " break;"
<< " case SPOT_LIGHT:"
<< " color += spotLight(light_idx, ...);"
<< " break;"
<< " case CINEMA_LIGHT:"
<< " color += cinemaLight(light_idx, ...);"
<< " break;"
<< " }"
<< " }"
<< " vFragColor = vec4(color, ...);"
<< "}"

I hope that this stage and the additional changes make it into OpenSG.
It would be nice if you could also take a look if I had made some
terrible design flaws. This was really a lot of work and I hope to build
on it in the near future.

Best,
Johannes


(*) I have also tried to add an override for the shader code itself
beside from the overrides to the buffer chunks. But that did not work
well and I have limit the stage by providing the necessary shader source
code. I did have problems with the shader #version and #extensions
primitives that must be in the first line of the shader code.

Loading...