- Home /
SRP based Clustered Shading, weird flickering (maybe due to computebuffers out of sync i guess)
This might takes time to read;
I'm working on a tiny project, which is Building a Clustered Shading RP with SRP, I managed to complete the pre-computations of cluster filling and light assigning with Compute Shaders, and after that are two context.DrawRenders()
calls to do Light Assignment Debug and Opaque. Here is a glimpse of my coding of this part:
// Above is Cluster Filling and Light Assignment
// 5. Debug Light Assignment
mainCmdBuffer.SetGlobalBuffer(IdManager.ClusterFlagsId, computeBuffers.clusterFlagsBuffer);
mainCmdBuffer.SetGlobalBuffer(IdManager.pointLightGridId, computeBuffers.pointLightGridBuffer);
mainCmdBuffer.SetGlobalBuffer(IdManager.spotLightGridId, computeBuffers.spotLightGridBuffer);
ExecuteBuffer();
var debugDrawingSettings = new DrawingSettings(debugLightAssignShaderTagId, sortingSettings){
enableDynamicBatching = useDynamicBatching,
enableInstancing = useGPUInstancing
};
context.DrawRenderers(cullingResults, ref debugDrawingSettings, ref filteringSettings);
// 6. Opaque Pass
mainCmdBuffer.SetGlobalBuffer(IdManager.pointLightsId, computeBuffers.pointLightsBuffer);
mainCmdBuffer.SetGlobalBuffer(IdManager.pointLightGridId, computeBuffers.pointLightGridBuffer);
mainCmdBuffer.SetGlobalBuffer(IdManager.pointLightIndexListId, computeBuffers.pointLightIndexListBuffer);
mainCmdBuffer.SetGlobalBuffer(IdManager.spotLightsId, computeBuffers.spotLightsBuffer);
mainCmdBuffer.SetGlobalBuffer(IdManager.spotLightGridId, computeBuffers.spotLightGridBuffer);
mainCmdBuffer.SetGlobalBuffer(IdManager.spotLightIndexListId, computeBuffers.spotLightIndexListBuffer);
ExecuteBuffer();
sortingSettings = new SortingSettings(camera) { criteria = SortingCriteria.CommonOpaque }; // -- pass camera to determine orthographic / distance-based sorting // -- CommonOpaque: front-to-back
// sortingSettings.criteria = SortingCriteria.OptimizeStateChanges;
drawingSettings = new DrawingSettings(litShaderTagId, sortingSettings){
enableDynamicBatching = useDynamicBatching,
enableInstancing = useGPUInstancing
};
filteringSettings = new FilteringSettings(RenderQueueRange.opaque); // -- draw transparent objects later
context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
I built a simple scene to test, and Light Assign Debug seem to work fine, but weird flickering appeared in Opauqe Pass:
Videos: Light Assign Debug: https://drive.google.com/file/d/1yBVq38UZbG2md7I1rxSdT4Q0NyKVet18/view?usp=sharing Opaque Pass: https://drive.google.com/file/d/1NODAEZ04QdXd6zpD7KCDoZxJihmG4kP_/view?usp=sharing
You can see that Opaque Lighting worked well at the start, but flickering appeared 2-3 seconds later, the picture flickered and most lights disappeared and cluster screen tile appeared, What gave me a hint is that at around 6-7 seconds of this video, I clicked 'Capture in RenderDoc' and it turned correct magically. Since 'Capture in RenderDoc' would (nearly) pause a frame, so I guess the problem is that LightIndexList
and LightGrid
these two Compute Buffers I pass as the global buffer, somehow didn't acquired the correct value, out of sync maybe, and the pause of 'Capture in RenderDoc' somehow made them synchronized again.
Anybody knows what is really going wrong with my code, and how to fix it ?
Thanks for your reading, if you have similar problems, maybe we can discuss in comments.