Improving Shadows on Ogre 2.1
-
- OGRE Team Member
- Posts: 5436
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1343
Re: Improving Shadows on Ogre 2.1
HW bilinear PCF is what you're missing:
We sample in those locations e.g. in location 1 and the HW will perform 2x2 PCF on samples 00 01 10 and 11. Sampling location 2 will perform 2x2 PCF on samples 10 20 11 and 21
Thus for 3x3 PCF we need to perform 4 samples.
We sample in those locations e.g. in location 1 and the HW will perform 2x2 PCF on samples 00 01 10 and 11. Sampling location 2 will perform 2x2 PCF on samples 10 20 11 and 21
Thus for 3x3 PCF we need to perform 4 samples.
You do not have the required permissions to view the files attached to this post.
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 169
Re: Improving Shadows on Ogre 2.1
ohhh I see, so if I implement a 16 samples that should be called 5x5, and 25 samp 6x6? is that ok?
also: the offset[0] in 4x4 is (0,0)... shouldn't be that (-1,-1)? so its centered? in fact by doing that I notice that when having peter panning (or acne) I have the same amount on both sides of an object, when its (0,0) I have more peter panning (or acne) in one side, so I think it need to be centered
thank you!
also: the offset[0] in 4x4 is (0,0)... shouldn't be that (-1,-1)? so its centered? in fact by doing that I notice that when having peter panning (or acne) I have the same amount on both sides of an object, when its (0,0) I have more peter panning (or acne) in one side, so I think it need to be centered
thank you!
-
- OGRE Team Member
- Posts: 5436
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1343
Re: Improving Shadows on Ogre 2.1
Sounds correct
I have no idea. I wonder if you're right and it could improve quality.xrgo wrote: ↑Tue Apr 14, 2020 9:55 pm also: the offset[0] in 4x4 is (0,0)... shouldn't be that (-1,-1)? so its centered? in fact by doing that I notice that when having peter panning (or acne) I have the same amount on both sides of an object, when its (0,0) I have more peter panning (or acne) in one side, so I think it need to be centered
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 169
Re: Improving Shadows on Ogre 2.1
thanks!
I've made a PR:
https://github.com/OGRECave/ogre-next/pull/85
Can I also ask where in your todo list is the stable pssm xD? viewtopic.php?p=514707#p514707
to be honest the only reason I need pcf 6x6 is to avoid a little bit the flickering due to unstable pssm (which in VR is super duper annoying), implementing pcf 6x6 is in my skillset, but making the shadows stable nope (I tried)
Thanks!!!
I've made a PR:
https://github.com/OGRECave/ogre-next/pull/85
Can I also ask where in your todo list is the stable pssm xD? viewtopic.php?p=514707#p514707
to be honest the only reason I need pcf 6x6 is to avoid a little bit the flickering due to unstable pssm (which in VR is super duper annoying), implementing pcf 6x6 is in my skillset, but making the shadows stable nope (I tried)
Thanks!!!
-
- OGRE Team Member
- Posts: 5436
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1343
Re: Improving Shadows on Ogre 2.1
I thought I had replied about this but since it was only in my head:
That technique (stable PSSM) has a few strong drawbacks which is why I stopped caring about it (at least that particular implementation):
1. The way the current PSSM works is by dividing the visible area in chunks: The pictured scenario is the ideal one (light perpendicular to lighting direction), but basically each split contains the most tight shadow map to get the most quality out of it (without sacrificing correctness within that split).
However when you rotate the camera or change the lighting direction, the size and shape of these splits change (the green, yellow and red rectangles), and that's what causes the instability.
Moving the camera doesn't change the shape of the splits, thus it is stable to position-only changes.
2. This alternate way of calculating PSSM splits was much more basic and simple: It just grows from the center of the camera. The green split wastes space by including geometry in the shadow map which is behind the camera. But the benefit of doing that is that rotating the camera is now very stable as the split is exactly the same irrespective of camera rotations.
The problem starts... as we pay attention to the further away splits. There's a lot of wasted space (the yellow split even includes objects that were rendered for the green split; the red one includes the yellow and green ones) which will affect both performance and quality.
Like 70% of the shadow map space for the red split is wasted. Far away splits already have poor quality, this makes it a lot worse.
Perhaps a fusion of both methods (using a concentric square/sphere centered around the camera for the 1st and maybe the 2nd split; while using optimal split for the 3rd split) could be a better balance or compromise between both methods: Notice that the green and yellow split are just concentric squares/spheres while the red one was calculated to tightly fit the frustum.
That technique (stable PSSM) has a few strong drawbacks which is why I stopped caring about it (at least that particular implementation):
1. The way the current PSSM works is by dividing the visible area in chunks: The pictured scenario is the ideal one (light perpendicular to lighting direction), but basically each split contains the most tight shadow map to get the most quality out of it (without sacrificing correctness within that split).
However when you rotate the camera or change the lighting direction, the size and shape of these splits change (the green, yellow and red rectangles), and that's what causes the instability.
Moving the camera doesn't change the shape of the splits, thus it is stable to position-only changes.
2. This alternate way of calculating PSSM splits was much more basic and simple: It just grows from the center of the camera. The green split wastes space by including geometry in the shadow map which is behind the camera. But the benefit of doing that is that rotating the camera is now very stable as the split is exactly the same irrespective of camera rotations.
The problem starts... as we pay attention to the further away splits. There's a lot of wasted space (the yellow split even includes objects that were rendered for the green split; the red one includes the yellow and green ones) which will affect both performance and quality.
Like 70% of the shadow map space for the red split is wasted. Far away splits already have poor quality, this makes it a lot worse.
Perhaps a fusion of both methods (using a concentric square/sphere centered around the camera for the 1st and maybe the 2nd split; while using optimal split for the 3rd split) could be a better balance or compromise between both methods: Notice that the green and yellow split are just concentric squares/spheres while the red one was calculated to tightly fit the frustum.
You do not have the required permissions to view the files attached to this post.
-
- OGRE Team Member
- Posts: 5436
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1343
Re: Improving Shadows on Ogre 2.1
UPDATE: Writing things down helps a lot.
I tried a 20 minute fix and I got the hybrid working. As expected the quality is lower (more shadows look a lot more staircase for the same resolution) but are stable to camera rotations.
I will push tomorrow to its own branch for evaluation.
UPDATE 2: The only thing so far I see broken is PSSM split smooth fading between the splits that are using different methods, which is not a big surprise.
I tried a 20 minute fix and I got the hybrid working. As expected the quality is lower (more shadows look a lot more staircase for the same resolution) but are stable to camera rotations.
I will push tomorrow to its own branch for evaluation.
UPDATE 2: The only thing so far I see broken is PSSM split smooth fading between the splits that are using different methods, which is not a big surprise.
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 169
Re: Improving Shadows on Ogre 2.1
Fantastic!!
you should have a look at this CSM implementation
viewtopic.php?t=71142
I remember it to be perfect when I use it back in my 1.9 days, has split smooth fading, 100% stable, even the poisson filtering was stable (it's in world space) (but pcf might be better). There's a download link at the bottom of the first post.
Maybe is easier to integrate it as an option?
edit: ohhh I see here in the still alive pictures viewtopic.php?p=467151#p467151 that this works as you mentioned before (concentric splits)
you mean this for the current implementation?, if that so, I can confirm it's not stable to position-only changes (just checked with the sample by just pressing WASD, no mouse move) for that to be stable I think the shadow map should move/snap in a world-size texel sizedark_sylinc wrote: ↑Wed Apr 15, 2020 5:28 am Moving the camera doesn't change the shape of the splits, thus it is stable to position-only changes.
wouldn't that cause the last split to not be stable? I usually set stuff so that the last split looks very low res so the problem wold be noticeable, and in some cases I use only two splits.
you should have a look at this CSM implementation
viewtopic.php?t=71142
I remember it to be perfect when I use it back in my 1.9 days, has split smooth fading, 100% stable, even the poisson filtering was stable (it's in world space) (but pcf might be better). There's a download link at the bottom of the first post.
Maybe is easier to integrate it as an option?
edit: ohhh I see here in the still alive pictures viewtopic.php?p=467151#p467151 that this works as you mentioned before (concentric splits)
-
- OGRE Team Member
- Posts: 5436
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1343
Re: Improving Shadows on Ogre 2.1
That is correct.xrgo wrote: ↑Wed Apr 15, 2020 11:47 am you mean this for the current implementation?, if that so, I can confirm it's not stable to position-only changes (just checked with the sample by just pressing WASD, no mouse move) for that to be stable I think the shadow map should move/snap in a world-size texel size
But the level of stability is on a whole different level when compared to camera rotation.
Correct, the last splits wouldn't be stable
You're vastly underestimating how bad it looks on the last splits. It looks really, really bad. As in "wtf is that?? it doesn't even resemble a shadow" bad.
Yes, and as described in that post, that CSM implementation had issues based on the light direction.xrgo wrote: ↑Wed Apr 15, 2020 11:47 am edit: ohhh I see here in the still alive pictures viewtopic.php?p=467151#p467151 that this works as you mentioned before (concentric splits)
-
- OGRE Team Member
- Posts: 5436
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1343
Re: Improving Shadows on Ogre 2.1
I've added the v2-2-stable-pssm branch.
Check it out.
Use:
In compositor node scripts to have the 1st split use the stable variant.
Use num_stable_splits >= num_splits to have all splits use the stable variant (num_stable_splits > num_splits is the same as num_stable_splits = num_splits).
In code it's ShadowTextureDefinition::numStableSplits
There are artifacts (for some reason, yet to be researched) when the pixels switch from stable to the unstable variant. If it weren't for that, I would merge it with ifd branch
Edit: And just like that... the artifacts are gone. I cannot reproduce them anymore. Maybe I fixed something while preparing the code for pushing to git?
Edit 2: Could you test how it works for you? If all is well, I'll merge to the main v2-2-irradiance-field branch
Check it out.
Use:
Code: Select all
num_stable_splits 1
Use num_stable_splits >= num_splits to have all splits use the stable variant (num_stable_splits > num_splits is the same as num_stable_splits = num_splits).
In code it's ShadowTextureDefinition::numStableSplits
There are artifacts (for some reason, yet to be researched) when the pixels switch from stable to the unstable variant. If it weren't for that, I would merge it with ifd branch
Edit: And just like that... the artifacts are gone. I cannot reproduce them anymore. Maybe I fixed something while preparing the code for pushing to git?
Edit 2: Could you test how it works for you? If all is well, I'll merge to the main v2-2-irradiance-field branch
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 169
-
- OGRE Team Member
- Posts: 5436
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1343
Re: Improving Shadows on Ogre 2.1
I just checked and it doesn't seem like I forgot to commit anything.
ConcentricShadowCamera is defined in OgreMain/include/OgreShadowCameraSetupConcentric.h
But I just noticed that this was missing, which is important for MSVC:
Could you pull & try again?
ConcentricShadowCamera is defined in OgreMain/include/OgreShadowCameraSetupConcentric.h
But I just noticed that this was missing, which is important for MSVC:
Code: Select all
#include "OgreStableHeaders.h"
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 169
Re: Improving Shadows on Ogre 2.1
Thanks! yes that was it
its working, but as you mentioned only for rotation changes, not for position changes, so I am 100% certain that is not going to improve anything in VR since its imposible to not translate your head as you look around, even when you think you're standing still camera position values change, so it will flicker
its missing this important part (from the csm code):
its working, but as you mentioned only for rotation changes, not for position changes, so I am 100% certain that is not going to improve anything in VR since its imposible to not translate your head as you look around, even when you think you're standing still camera position values change, so it will flicker
its missing this important part (from the csm code):
Code: Select all
// Round local x/y position based on a world-space texel; this helps to reduce
// jittering caused by the projection moving with the camera
Real worldTexelSize = (texCam->getOrthoWindowWidth()) / texCam->getViewport()->getActualWidth();
//convert world space camera position into light space
Vector3 lightSpacePos = q.Inverse() * pos;
//snap to nearest texel
lightSpacePos.x -= fmod(lightSpacePos.x, worldTexelSize);
lightSpacePos.y -= fmod(lightSpacePos.y, worldTexelSize);
//convert back to world space
pos = q * lightSpacePos;
I am going to try now anywaysdark_sylinc wrote: ↑Wed Apr 15, 2020 2:24 pm But the level of stability is on a whole different level when compared to camera rotation.
yeah I noticed xD maybe I can play with resolution, but thanks for giving an easy way to change numStableSplitsdark_sylinc wrote: ↑Wed Apr 15, 2020 2:24 pm It looks really, really bad. As in "wtf is that?? it doesn't even resemble a shadow" bad.
I used it a lot back in the days and never noticed any issue, might be a very rare casedark_sylinc wrote: ↑Wed Apr 15, 2020 2:24 pm Yes, and as described in that post, that CSM implementation had issues based on the light direction.
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 169
Re: Improving Shadows on Ogre 2.1
OK, I tried in VR and if I "stand still" it flicks like 80% less than before, but if I move around it flicks like 10% less than before. knowing that the later case is practically 100% of the time in VR is not a great gain, considering that it also looks more pixelated, the only way is to make it stable for position changes.
I tried to integrate the code in csm
and it flicks waaaaaay less frecuent, but the intensity of the flick is the same (not sure if that makes sense), and the fact that happens less periodically makes it more distracting xD, so it have to be perfect :/
Thanks!
I tried to integrate the code in csm
Code: Select all
Vector3 dir;
Quaternion q;
// Calculate texCam direction, which same as directional light direction
dir = -light->getDerivedDirection(); // backwards since point down -z
dir.normalise();
Vector3 up = Vector3::UNIT_Y;
// Check it's not coincident with dir
if( Math::Abs( up.dotProduct( dir ) ) >= 1.0f )
{
// Use camera up
up = Vector3::UNIT_Z;
}
// cross twice to rederive, only direction is unaltered
Vector3 left = dir.crossProduct( up );
left.normalise();
up = dir.crossProduct( left );
up.normalise();
// Derive quaternion from axes
q.FromAxes( left, up, dir );
// Round local x/y position based on a world-space texel; this helps to reduce
// jittering caused by the projection moving with the camera
Real worldTexelSize =
( texCam->getOrthoWindowWidth() ) / 2048;//hardcoded value to test
// convert world space camera position into light space
Vector3 lightSpacePos = q.Inverse() * shadowCameraPos;
// snap to nearest texel
lightSpacePos.x -= fmod( lightSpacePos.x, worldTexelSize );
lightSpacePos.y -= fmod( lightSpacePos.y, worldTexelSize );
lightSpacePos.z -= fmod( lightSpacePos.z, worldTexelSize );
// convert back to world space
shadowCameraPos = q * lightSpacePos;
Thanks!
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 169
Re: Improving Shadows on Ogre 2.1
ok, apparently this works (at least in the sample):
I just need to know how to get the split resolution for that division
Edit: doh... viewportRealSize!! seems to be working really perfectly on the sample, going to check in vr now
Edit2: OMG it looks really really really goooood, finally no more flickery mess, I am going to test other projects
Edit3: I tested a couple of other projects and is really good, I only get a tiny tiny flick sometimes but its just one pixel in the border of the shadow, its very very minimal (pretty sure is because the object casting that shadow is a rigid body with constraints that seems to be still but its actually vibrating a bit) so I'll call it perfect!
should I make a PR? I also had to add this:
I am going to sleep now, very very happy, thanks for everything, I love you <3
Code: Select all
Quaternion q = light->getParentSceneNode()->_getDerivedOrientationUpdated();
// Round local x/y position based on a world-space texel; this helps to reduce
// jittering caused by the projection moving with the camera
Real worldTexelSize =
( texCam->getOrthoWindowWidth() ) / 2048; //the first split is 2048 so it works perfectly int that split
// convert world space camera position into light space
Vector3 lightSpacePos = q.Inverse() * shadowCameraPos;
// snap to nearest texel
lightSpacePos.x -= fmod( lightSpacePos.x, worldTexelSize );
lightSpacePos.y -= fmod( lightSpacePos.y, worldTexelSize );
// convert back to world space
shadowCameraPos = q * lightSpacePos;
Edit: doh... viewportRealSize!! seems to be working really perfectly on the sample, going to check in vr now
Edit2: OMG it looks really really really goooood, finally no more flickery mess, I am going to test other projects
Edit3: I tested a couple of other projects and is really good, I only get a tiny tiny flick sometimes but its just one pixel in the border of the shadow, its very very minimal (pretty sure is because the object casting that shadow is a rigid body with constraints that seems to be still but its actually vibrating a bit) so I'll call it perfect!
should I make a PR? I also had to add this:
Code: Select all
static void createShadowNodeWithSettings( CompositorManager2 *compositorManager,
const RenderSystemCapabilities *capabilities,
const String &shadowNodeName,
const ShadowNodeHelper::
ShadowParamVec &shadowParams,
bool useEsm,
uint32 pointLightCubemapResolution=1024u,
Real pssmLambda=0.95f, Real splitPadding=1.0f,
Real splitBlend = 0.125f, Real splitFade = 0.313f,
uint32 numStableSplits = 0, <<<<<<<<<<<<<<<<<<<<<<<THIS (and the cpp impl obviously)
uint32 visibilityMask = VisibilityFlags::RESERVED_VISIBILITY_FLAGS );
-
- OGRE Contributor
- Posts: 267
- Joined: Wed Apr 23, 2014 3:49 pm
- Location: Bologna, Italy
- x 75
Re: Improving Shadows on Ogre 2.1
Yes, please! I've put VR on hold atm, but I'm interested in this anyway since I have the same problem when the car is stopped with the engine turned on (the camera has micro-shakes due to the engine vibration).
O.T.: I guess you have a similar problem with alpha masked fences. How do you alleviate the issue in that case?
Senior programmer at 505 Games; former senior engine programmer at Sandbox Games
Worked on: Racecraft Esport — Racecraft Coin-Op, Victory: The Age of Racing
-
- OGRE Contributor
- Posts: 267
- Joined: Wed Apr 23, 2014 3:49 pm
- Location: Bologna, Italy
- x 75
Re: Improving Shadows on Ogre 2.1
Yes, because when I made that PR I didn't take in account that splits could also being concentric (don't have the crystall ball ). Can't have a look at it atm, but I guess that the PSSM splits blend system can be easily adapted to work with your changes.dark_sylinc wrote: ↑Wed Apr 15, 2020 5:56 am UPDATE 2: The only thing so far I see broken is PSSM split smooth fading between the splits that are using different methods, which is not a big surprise.
Senior programmer at 505 Games; former senior engine programmer at Sandbox Games
Worked on: Racecraft Esport — Racecraft Coin-Op, Victory: The Age of Racing
-
- OGRE Team Member
- Posts: 5436
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1343
Re: Improving Shadows on Ogre 2.1
Actually the artifact is gone; and your code should work without modification since the input your code relies on isn't affected it (distance from view point to slice).TaaTT4 wrote: ↑Thu Apr 16, 2020 2:55 pmYes, because when I made that PR I didn't take in account that splits could also being concentric (don't have the crystall ball ). Can't have a look at it atm, but I guess that the PSSM splits blend system can be easily adapted to work with your changes.dark_sylinc wrote: ↑Wed Apr 15, 2020 5:56 am UPDATE 2: The only thing so far I see broken is PSSM split smooth fading between the splits that are using different methods, which is not a big surprise.
Anyway the artifact doesn't seem to be anywhere now so I'm guessing it was a bug from one of the hardcoded values while I was prototyping.
Nice!!!xrgo wrote: ↑Thu Apr 16, 2020 4:27 am should I make a PR? I also had to add this:Code: Select all
static void createShadowNodeWithSettings( CompositorManager2 *compositorManager, const RenderSystemCapabilities *capabilities, const String &shadowNodeName, const ShadowNodeHelper:: ShadowParamVec &shadowParams, bool useEsm, uint32 pointLightCubemapResolution=1024u, Real pssmLambda=0.95f, Real splitPadding=1.0f, Real splitBlend = 0.125f, Real splitFade = 0.313f, uint32 numStableSplits = 0, <<<<<<<<<<<<<<<<<<<<<<<THIS (and the cpp impl obviously) uint32 visibilityMask = VisibilityFlags::RESERVED_VISIBILITY_FLAGS );
Yes please, submit a PR!
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 169
Re: Improving Shadows on Ogre 2.1
PR done: https://github.com/OGRECave/ogre-next/pull/86
yes, I can confirm that fade between splits works fine
thank you for everything
yes, I can confirm that fade between splits works fine
yes! I think that's one of the last flickering sources left, he problem is workarounded by using alpha blend instead of alpha clip, but that's expensive, I have no real solution for now, haven't looked much though
thank you for everything
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 169
Re: Improving Shadows on Ogre 2.1
thanks for the merge and the corrections/improvements!
I'll report in a few days if I see something strange
I'll report in a few days if I see something strange