Sign in to follow this  

EVSM is the best needed ?

This topic is 1111 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

EVSM is expensive, that demand RGBA32F texture on each cascade but from all my research that looks to be the best of the best actually.

Is it really needed to blur the depth in two pass : R32F depth map then RGBA32F using gaussian blur ?

Is it the really the best of the best actually and should be the method used today ?

 

EVSM shadow mapping pixel shader code :

float2 WarpDepth(in float depth, in float2 exponents)
{
  depth = 2.0f * depth - 1.0f;
  float pos =  exp( exponents.x * depth);
  float neg = -exp(-exponents.y * depth);
  return float2(pos, neg);
}

float4 ShadowDepthToEVSM(in float depth)
{
  float2 warpedDepth = WarpDepth(depth, float2(40.0f, 20.0f));
  return float4(warpedDepth.xy, warpedDepth.xy * warpedDepth.xy);
}
Edited by Alundra

Share this post


Link to post
Share on other sites

I've read little bit about EVSM, but I'm using VSM and I don't think that I'm the only one doing it. I like VSM approach because is portable and cheap.

 

Just rendering depth to two channels instead of one you can play with texture filters because your values are linear anyway. This explanation covers in detail everything you need to know to blur the SM and some other methods. It has HLSL code. This post covers from the top to the bottom with GLSL. Today most of the lights in a scene are culled to write to the Shadow Map. I've seen games that uses just the Sun -  a simple direction light - to cast shadows. Simple VSM with the Lighting Bleeding correction and some improvements can effective simulate a nice scene.

 

Also, if you want to take a look at my shaders you can download here an executable I did using DirectX™ 11.

Edited by Irlan

Share this post


Link to post
Share on other sites

Light-Bleeding correction :

float p_max = smoothstep(0.20f, 1.0f, variance / (variance + d*d));

I tried your sample but I got a weird result, far to be good, using A and D I can only move forward backward but can't rotate the camera and I got bad quality shadow.

The result I got : http://zupimages.net/up/14/48/41fw.png

Here result with my simple cascaded shadow mapping : http://zupimages.net/up/14/48/uirb.png

Edited by Alundra

Share this post


Link to post
Share on other sites

Light-Bleeding correction :

float p_max = smoothstep(0.20f, 1.0f, variance / (variance + d*d));

I tried your sample but I got a weird result, far to be good, using A and D I can only move forward backward but can't rotate the camera and I got bad quality shadow.

The result I got : http://zupimages.net/up/14/48/41fw.png

Here result with my simple cascaded shadow mapping : http://zupimages.net/up/14/48/uirb.png

Are you using PCF or interpolation or both in your example?

According to this I think everything is working as it should. AFAIK this is the way that VSM works, the edges are pre-filtered before can be sampled.

Also, in your picture the camera is very far, and I coudn't see if the edges are soft like the VSM approach. I'll take a look in my code anyway and see if I did something weird.

Edited by Irlan

Share this post


Link to post
Share on other sites

I simply use 4 cascade R32F depth map + poisson disk 8 samples on the picture I showed.

Oh, I see. That is why is much better than the brute-force VSM. I think that this approach is a little bit slower than VSM or SAVSM (though I did never implemented this one). 
 
One problem may be that the fact you're using 8 samples instead of just the simple Variance + Chebyshev Probabilistic Upper Bound approach, and this relates to PCF in some sword of way; applying a filter to the final depth it is fine, not the depth itself before can be compared with the position in ligh-space depth; this is just an opinion you may not agree. Everything that can retire all the for loops of the pixel shader - when possible - it is good for GPU performance as you already know.
 
I'm running in a NVIDIA™ 8400GS and the performance it is quite good when doing pixel instructions using VSM without any filter and MS - though I have to pick one in order to have blurry shadows.

Share this post


Link to post
Share on other sites

I've checked my shaders and code and everything is fine. The way it is appearing is the fact that I didn't applied any stepping filter.

/* VARIANCE SHADOW MAPPING. */
float linstep( float _fLow, float _fHigh, float _fV ) {
	return saturate( ( _fV - _fLow ) / ( _fHigh - _fLow ) );
}

float ChebyshevVariance( in float2 _vMoments, float _fComp ) {
	/* VARIANCE. */
	float fVar = max( _vMoments.y - ( _vMoments.x * _vMoments.x ), -0.005 );

	/* UPPER BOUND. */
	float fD = _fComp - _vMoments.x;
	float fP = _fComp <= _vMoments.x;
	float fPMax = fVar / ( fVar + fD * fD );
	
	return max( fP, linstep( 0.5, 1.0, fPMax ) );
}

float VsmShadowLookUp( in float2 _vP, float _fComp ) {
	return ChebyshevVariance( g_t2dShadowMap.Sample( g_ssLinearBorder, _vP ).xy, _fComp );
}

/* A POINT-TEXTURE-SPACE INTERSECTION ROUTINE. */

bool PointTextureSpace( in float2 _vP ) {
	return _vP.x >= 0.0 && _vP.x <= 1.0 &&
	       _vP.y >= 0.0 && _vP.y <= 1.0;
}

void Main( in VS_OUT _voOut, out float4 _vOutColor : SV_TARGET ) {
	float fShadow = 1.0;
	if ( PointTextureSpace( _voOut.vLightTexAndDepth.xy ) ) {
		fShadow = VsmShadowLookUp(_voOut.vLightTexAndDepth.xy, _voOut.vLightTexAndDepth.z);
	}
	_vOutColor.xyz = mMaterial.vDiffuse.xyz * fShadow;
	_vOutColor.w = 1.0;
}

The only thing I did changed is that I'm using the method explained in GPU Gems 3 that has 3 tweaks less.

 

After reading for a while looks like EVSM is a much better path to follow. Actually this link redirects you to an nice set of explanations of various methods, and the EVSM approach looks promising and I am going to implement tomorrow. He is saying the same I told you: avoid filtering step functions like PCF or something. The lighting bleeding issue looks gets corrected when using EVSM also.

 

Now I don't know where I'm going to find time to read all his publications that looks promising BTW. Anyway, I hope it helps.

Share this post


Link to post
Share on other sites

Light-Bleeding correction :

float p_max = smoothstep(0.20f, 1.0f, variance / (variance + d*d));

I tried your sample but I got a weird result, far to be good, using A and D I can only move forward backward but can't rotate the camera and I got bad quality shadow.

The result I got : http://zupimages.net/up/14/48/41fw.png

Here result with my simple cascaded shadow mapping : http://zupimages.net/up/14/48/uirb.png

As promised I did check the example. In the example I was using a 256x256 texture resolution. Changing to 512x512 definitely gives more precision. The results:

 

nn0cva.jpg

 

If someone see this post, I uploaded a example of ESM and VSM with a 3x3 Box Blur on this link; you can change the size of the kernel in the shaders; there is an source code of the high-level view of the shader and blur passes. I'll post a example of the EVSM when I finish. Hope can help.

 

Cheers,

Irlan

Edited by Irlan

Share this post


Link to post
Share on other sites

This topic is 1111 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this