Hi,
I am using DrawMeshInstancedIndirect in order to draw a lot of objects on a terrain mesh. Small issue - This draws objects in every shadow cascade, regardless of whether the object actually lies within that cascade. This is leading to each object being rendered 4 times for the shadow pass instead of just once.
In order to solve this, I would like to sort the objects into 4 groups based on which shadow cascade they are in.
I already have a framework set up which uses a CommandBuffer to draw each set of objects in the correct order in the correct shadow cascade.
My issue is with the calculation to determine which shadow cascade my objects lie in. The rest works fine.
My initial understanding was that in order to calculate which shadow cascade a position is in, itâs a simple distance check:
float percentageToShadowDistance = distance(_WorldSpaceCameraPosition, worldPos) / shadowDistance;
if (percentageToShadowDistance < _CascadeSplits.x)
{
//We are in cascade 0
}
//And so on
But it appears that this is not the case. When comparing the true shadow cascade transition to the one computed from distance, it is slightly off. There is a gap where the cascade changes after where I compute that transition to be. This gap changes shape based on camera position and FOV. I suspect it has something to do with one of the cameraâs matrices, but I donât know where to go from here.
Any assistance would be greatly appreciated, as Iâve not been able to find anything on this.
Cheers!
I canât directly suggest a solution, but is there something being overlooked? An object could easily be in more than one cascade, such as if it is large, and depending on the render pipeline or custom lighting shaders, etc., there can also be a transition overlap between cascades.
Iâll need to introduce a slight overlap or investigate performing some form of more precise culling in the vertex shader so that objects donât pop in and out at cascade edges. This could mean rendering two objects at cascade borders, but still a significant performance improvement over rendering 4 objects everywhere!
Oh, for sure, I was just pointing out that this will necessarily involve more nuance than âwhich shadow cascade my objects lie inâ, which you may have already known anyway.
âWeightsâ is a boolean mask where only one component (x, y, z or w) will be greater than 0 at once. The component that is greater than 0 corresponds to the shadow cascade the world position lies in.
I introduced an overlap factor (set to 10, currently) which allows world positions to lie within two shadow cascades at the border. In âweights + weights2â, two components can be greater than 0 at a time.
In this image, red corresponds to the nearest shadow cascade. Green corresponds to the second, and blue corresponds to the third. You can see that the yellow area is red + green, so objects here will be rendered in two shadow cascades to provide the overlap I require.
Cyan (green + blue) is the same.
The code automatically adjusts to two cascades or just 1 cascade without issue.
Hope this helps anyone in the future
In what version does it works? In 2023 it does not working. All this code is marked as deprecated and there is no obvious replacement in UnityCG.cginc. unity_ShadowSplitSpheres[0]-[3] is all return purple color.