Blend between splits and fade in last one
- TaaTT4
- OGRE Contributor
- Posts: 267
- Joined: Wed Apr 23, 2014 3:49 pm
- Location: Bologna, Italy
- x 75
- Contact:
Blend between splits and fade in last one
I'm far from being a shaders guru, so I ask for your help.
Is it possible to fade in the last PSSM split based on shadow distance from the camera?
What i want to avoid is the shadows pop out effect when the last split becomes visible.
I've seen some other games (Assetto Corsa for example) doing something similar.
[edit] Title changed to reflect content of my own reply post
Senior programmer at 505 Games; former senior engine programmer at Sandbox Games
Worked on: Racecraft Esport — Racecraft Coin-Op, Victory: The Age of Racing
- TaaTT4
- OGRE Contributor
- Posts: 267
- Joined: Wed Apr 23, 2014 3:49 pm
- Location: Bologna, Italy
- x 75
- Contact:
Re: Blend splits and fade out last one
A little step toward being a shaders guru
Replace this block in PixelShader_ps
Code: Select all
@property( hlms_pssm_splits )
float fShadow = 1.0;
if( inPs.depth <= passBuf.pssmSplitPoints@value(CurrentShadowMap) )
fShadow = getShadow( texShadowMap[@value(CurrentShadowMap)], inPs.posL0, passBuf.shadowRcv[@counter(CurrentShadowMap)].invShadowMapSize );
@foreach( hlms_pssm_splits, n, 1 ) else if( inPs.depth <= passBuf.pssmSplitPoints@value(CurrentShadowMap) )
fShadow = getShadow( texShadowMap[@value(CurrentShadowMap)], inPs.posL@n, passBuf.shadowRcv[@counter(CurrentShadowMap)].invShadowMapSize );
@end @end @property( !hlms_pssm_splits && hlms_num_shadow_maps && hlms_lights_directional )
float fShadow = getShadow( texShadowMap[@value(CurrentShadowMap)], inPs.posL0, passBuf.shadowRcv[@counter(CurrentShadowMap)].invShadowMapSize );
@end
Code: Select all
@property( hlms_pssm_splits )
@psub( pssm_split_n, hlms_pssm_splits, 1 )
@pset( pssm_split_blend_m, 0 )
@padd( pssm_split_blend_m_plus_1, pssm_split_blend_m, 1 )
float pssm_split_blend_point0 = lerp( 0.0, passBuf.pssmSplitPoints@value(pssm_split_blend_m), 0.9 );
@foreach( pssm_split_n, n, 1 ) float pssm_split_blend_point@n = lerp( passBuf.pssmSplitPoints@value(pssm_split_blend_m), passBuf.pssmSplitPoints@value(pssm_split_blend_m_plus_1), 0.9 );
@add( pssm_split_blend_m, 1 )
@add( pssm_split_blend_m_plus_1, 1 )
@end
float fShadow = 1.0;
float fShadowNextSplit = 1.0;
if( inPs.depth <= passBuf.pssmSplitPoints@value(CurrentShadowMap) )
{
fShadow = getShadow( texShadowMap[@value(CurrentShadowMap)], inPs.posL0, passBuf.shadowRcv[@counter(CurrentShadowMap)].invShadowMapSize );
if( inPs.depth > pssm_split_blend_point0 )
{
fShadowNextSplit = getShadow( texShadowMap[@value(CurrentShadowMap)], inPs.posL@value(CurrentShadowMap), passBuf.shadowRcv[@value(CurrentShadowMap)].invShadowMapSize );
fShadow = lerp( fShadow, fShadowNextSplit, (inPs.depth - pssm_split_blend_point0) / (passBuf.pssmSplitPoints0 - pssm_split_blend_point0) );
}
}
@foreach( pssm_split_n, n, 1 ) else if( inPs.depth <= passBuf.pssmSplitPoints@value(CurrentShadowMap) )
{
fShadow = getShadow( texShadowMap[@value(CurrentShadowMap)], inPs.posL@n, passBuf.shadowRcv[@counter(CurrentShadowMap)].invShadowMapSize );
if( inPs.depth > pssm_split_blend_point@n )
{
fShadowNextSplit = getShadow( texShadowMap[@value(CurrentShadowMap)], inPs.posL@value(CurrentShadowMap), passBuf.shadowRcv[@value(CurrentShadowMap)].invShadowMapSize );
fShadow = lerp( fShadow, fShadowNextSplit, (inPs.depth - pssm_split_blend_point@n) / (passBuf.pssmSplitPoints@n - pssm_split_blend_point@n) );
}
}
@end
@psub( pssm_split_m, pssm_split_n, 1 )
else if( inPs.depth <= passBuf.pssmSplitPoints@value(pssm_split_n) )
{
fShadow = getShadow( texShadowMap[@value(CurrentShadowMap)], inPs.posL@value(CurrentShadowMap), passBuf.shadowRcv[@counter(CurrentShadowMap)].invShadowMapSize );
float pssmSplitPointFade = lerp( passBuf.pssmSplitPoints@value(pssm_split_m), passBuf.pssmSplitPoints@value(pssm_split_n), 0.5 );
if( inPs.depth > pssmSplitPointFade )
{
fShadow = lerp( fShadow, 1.0, (inPs.depth - pssmSplitPointFade) / (passBuf.pssmSplitPoints@value(pssm_split_n) - pssmSplitPointFade) );
}
}
@end @property( !hlms_pssm_splits && hlms_num_shadow_maps && hlms_lights_directional )
float fShadow = getShadow( texShadowMap[@value(CurrentShadowMap)], inPs.posL0, passBuf.shadowRcv[@counter(CurrentShadowMap)].invShadowMapSize );
@end
As a bonus track, you'll receive also blending between the various splits.
Check the "Blend between Cascades" section at this link to more info about what I'm talking about.
[edit]
Fixed an issue when spotlights are used (CurrentShadowMap value not updated)
Fade in starts at the half of the last split (instead of beginning)
Senior programmer at 505 Games; former senior engine programmer at Sandbox Games
Worked on: Racecraft Esport — Racecraft Coin-Op, Victory: The Age of Racing
- GlowingPotato
- Goblin
- Posts: 211
- Joined: Wed May 08, 2013 2:58 pm
- x 10
Re: Blend between splits and fade in last one
You should submit a pull request. Kudos!
-
- OGRE Expert User
- Posts: 1227
- Joined: Thu Dec 11, 2008 7:56 pm
- Location: Bristol, UK
- x 157
Re: Blend between splits and fade in last one
+1GlowingPotato wrote:That's so cool!
You should submit a pull request. Kudos!
- dark_sylinc
- OGRE Team Member
- Posts: 5299
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1280
- Contact:
Re: Blend between splits and fade in last one
- TaaTT4
- OGRE Contributor
- Posts: 267
- Joined: Wed Apr 23, 2014 3:49 pm
- Location: Bologna, Italy
- x 75
- Contact:
Re: Blend between splits and fade in last one
The fade-in effect happens just in the last split and is pretty much "free" as it just consist in a lerp.
Anyway, I didn't see any appreciable performance impact.
Since the blending addition mostly depends on shadows far clip, splits count and how much of the n-1 first splits must be blended with the next one, with different parameters the performance impact could become significant.
To test those additions we have used:
- 4 splits of 8K, 4K, 4K and 4K (from the nearest to the farthest)
- 200m as shadows far clip
- 10% of evey split blended with the next one
Senior programmer at 505 Games; former senior engine programmer at Sandbox Games
Worked on: Racecraft Esport — Racecraft Coin-Op, Victory: The Age of Racing
- dark_sylinc
- OGRE Team Member
- Posts: 5299
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1280
- Contact:
Re: Blend between splits and fade in last one
Yes, sorry. I meant blending.TaaTT4 wrote:Do you mean blending?
Very interestingTaaTT4 wrote:Anyway, I didn't see any appreciable performance impact.
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 168
Re: Blend between splits and fade in last one
I only made the last split to fadeout just the last 10%, no everything, and changed lerp to mix for glsl:
Code: Select all
@property( hlms_pssm_splits )
@psub( pssm_split_n, hlms_pssm_splits, 1 )
@pset( pssm_split_blend_m, 0 )
@padd( pssm_split_blend_m_plus_1, pssm_split_blend_m, 1 )
float pssm_split_blend_point0 = mix( 0.0, pass.pssmSplitPoints@value(pssm_split_blend_m), 0.9 );
@foreach( hlms_pssm_splits, n, 1 )
float pssm_split_blend_point@n = mix( pass.pssmSplitPoints@value(pssm_split_blend_m), pass.pssmSplitPoints@value(pssm_split_blend_m_plus_1), 0.9 );
@add( pssm_split_blend_m, 1 )
@add( pssm_split_blend_m_plus_1, 1 )
@end
float fShadow = 1.0;
float fShadowNextSplit = 1.0;
if( inPs.depth <= pass.pssmSplitPoints@value(CurrentShadowMap) )
{
fShadow = getShadow( texShadowMap[@value(CurrentShadowMap)], inPs.posL0, pass.shadowRcv[@counter(CurrentShadowMap)].invShadowMapSize );
if( inPs.depth > pssm_split_blend_point0 )
{
fShadowNextSplit = getShadow( texShadowMap[@value(CurrentShadowMap)], inPs.posL@value(CurrentShadowMap), pass.shadowRcv[@value(CurrentShadowMap)].invShadowMapSize );
fShadow = mix( fShadow, fShadowNextSplit, (inPs.depth - pssm_split_blend_point0) / (pass.pssmSplitPoints0 - pssm_split_blend_point0) );
}
}
@foreach( pssm_split_n, n, 1 )
else if( inPs.depth <= pass.pssmSplitPoints@value(CurrentShadowMap) )
{
fShadow = getShadow( texShadowMap[@value(CurrentShadowMap)], inPs.posL@n, pass.shadowRcv[@counter(CurrentShadowMap)].invShadowMapSize );
if( inPs.depth > pssm_split_blend_point@n )
{
fShadowNextSplit = getShadow( texShadowMap[@value(CurrentShadowMap)], inPs.posL@value(CurrentShadowMap), pass.shadowRcv[@value(CurrentShadowMap)].invShadowMapSize );
fShadow = mix( fShadow, fShadowNextSplit, (inPs.depth - pssm_split_blend_point@n) / (pass.pssmSplitPoints@n - pssm_split_blend_point@n) );
}
}
@end
@psub( pssm_split_m, pssm_split_n, 1 )
else if( inPs.depth <= pass.pssmSplitPoints@value(pssm_split_n) )
{
fShadow = getShadow( texShadowMap[@value(pssm_split_n)], inPs.posL@value(pssm_split_n), pass.shadowRcv[@value(pssm_split_n)].invShadowMapSize );
if( inPs.depth > pssm_split_blend_point@value(pssm_split_n) )
{
fShadow = mix( fShadow, 1.0, (inPs.depth - pssm_split_blend_point@value(pssm_split_n)) / (pass.pssmSplitPoints@value(pssm_split_n) - pssm_split_blend_point@value(pssm_split_n)) );
}
}
@end
have to test performance yet
- TaaTT4
- OGRE Contributor
- Posts: 267
- Joined: Wed Apr 23, 2014 3:49 pm
- Location: Bologna, Italy
- x 75
- Contact:
Re: Blend between splits and fade in last one
Senior programmer at 505 Games; former senior engine programmer at Sandbox Games
Worked on: Racecraft Esport — Racecraft Coin-Op, Victory: The Age of Racing
- TaaTT4
- OGRE Contributor
- Posts: 267
- Joined: Wed Apr 23, 2014 3:49 pm
- Location: Bologna, Italy
- x 75
- Contact:
Re: Blend between splits and fade in last one
Enjoy!
Senior programmer at 505 Games; former senior engine programmer at Sandbox Games
Worked on: Racecraft Esport — Racecraft Coin-Op, Victory: The Age of Racing
- dark_sylinc
- OGRE Team Member
- Posts: 5299
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1280
- Contact:
Re: Blend between splits and fade in last one
Now shadows look prettier!
PS: Worked out of the box on Metal.
-
- Gremlin
- Posts: 184
- Joined: Sat Apr 16, 2016 9:25 pm
- x 19
Re: Blend between splits and fade in last one
- dark_sylinc
- OGRE Team Member
- Posts: 5299
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1280
- Contact: