Sign in to follow this  

Shadows

This topic is 2487 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

Hello,
I'm fighting for long time with shadows in my projects. Spent on it a lot of time and slowly getting angry and annoyed. I encountered two problems with two shadow mapping technique in Deferred Rendering:

1.
[url="http://img220.imageshack.us/i/vsm.png/"]Pic.1[/url]
[url="http://img257.imageshack.us/i/vsmblurred.png/"]Pic.2[/url]

VSM: First image is non blurred vsm, only with linear filtering. Doesn't look so bad.
But on second there's blurred one. And there comes the problem. Shadow looks is not even blurred, whole penumbra which should be soft is 'eaten', and pixel is not shadowed. I'm using G16R16F format. Really don't know what cause this error. Here is code:
Generating vsm:
[code]
VSOUTPUT_SHADOW VS_Shadow( float4 inPosition : POSITION )
{
// Output struct
VSOUTPUT_SHADOW OUT = (VSOUTPUT_SHADOW)0;

float4 worldPos = mul( inPosition, matWorld );

// Output the transformed position
OUT.vPosition = mul( worldPos, matLightViewProj );

// Output the scene depth
OUT.fDepth = length(mul(worldPos, matLightView).xyz) / 2048.0f;

return OUT;
}

float4 PS_Shadow( VSOUTPUT_SHADOW IN ) : COLOR0
{
// Output the scene depth
return float4(IN.fDepth, (IN.fDepth*IN.fDepth), 0.0f, 1.0f );
}
[/code]

Drawing vsm
[code]
float Vsm( float2 tex, float fragDepth )
{
fragDepth /= 2048.0f;
fragDepth -= 0.00001;

float lit = (float)0.0f;
float2 moments = tex2D(ShadowSampler, tex);

float E_x2 = moments.y;
float Ex_2 = moments.x * moments.x;
float variance = min(max(E_x2 - Ex_2, 0.0f) + 0.00001f, 1.0f);
float mD = (moments.x - fragDepth );
float mD_2 = mD * mD;
float p = variance / (variance + mD_2 );
lit = max( p, fragDepth <= moments.x );

return lit;
}

...
float fDepth = length( vLightPosition - vWorldPos );
float4 vProjCoord = mul( float4(vWorldPos, 1.0f), matLightViewProj );
vProjCoord /= vProjCoord.w;

// Rescale viewport to be [0,1] (texture coordinate space)
float2 shadowTex = vProjCoord.xy * float2(0.5, -0.5) + 0.5f;

float ShadowTerm = Vsm(shadowTex, fDepth);
ShadowTerm = saturate(ShadowTerm*2-1);
...
[/code]

2. [url="http://img143.imageshack.us/i/shadowpcferror.png/"]Pic.1[/url]
[url="http://img232.imageshack.us/i/shadowpcfbias.png/"]Pic.2[/url]

Second problems is with standard PCF Shadow Maps. Since i'm trying to get them working under deferred renderer, they're not working as they should.
On first pic there's really high biasing, caused by... don't know what. After huge increase of bias(Second Pic) removes biasing but shadow looks poorly and there is no PCF. Using R32F for shadow map.
Generating:
[code]
// Shadow generation vertex shader
VSOUTPUT_SHADOW VS_Shadow( float4 inPosition : POSITION )
{
// Output struct
VSOUTPUT_SHADOW OUT = (VSOUTPUT_SHADOW)0;

float4 worldPos = mul( inPosition, matWorld );

// Output the transformed position
OUT.vPosition = mul( worldPos, matLightViewProj );

// Output the scene depth
OUT.fDepth = OUT.vPosition.z;

return OUT;
}

float4 PS_Shadow( VSOUTPUT_SHADOW IN ) : COLOR
{
// Output the scene depth
return float4( IN.fDepth, IN.fDepth, IN.fDepth, 1.0f );
}
[/code]

Drawing:
[code]
float ShadowPCF(float4 vProjCoord)
{
// Generate the 9 texture co-ordinates for a 3x3 PCF kernel
float4 vTexCoords[9];

// Texel size
float fTexelSize = 1.0f / 512.0f;

// Grab the shadow term
float fShadowTerm = 0.0f;

vTexCoords[0] = vProjCoord;

vTexCoords[1] = vProjCoord + float4( -fTexelSize, 0.0f, 0.0f, 0.0f );
vTexCoords[2] = vProjCoord + float4( fTexelSize, 0.0f, 0.0f, 0.0f );
vTexCoords[3] = vProjCoord + float4( 0.0f, -fTexelSize, 0.0f, 0.0f );
vTexCoords[6] = vProjCoord + float4( 0.0f, fTexelSize, 0.0f, 0.0f );

vTexCoords[4] = vProjCoord + float4( -fTexelSize, -fTexelSize, 0.0f, 0.0f );
vTexCoords[5] = vProjCoord + float4( fTexelSize, -fTexelSize, 0.0f, 0.0f );
vTexCoords[7] = vProjCoord + float4( -fTexelSize, fTexelSize, 0.0f, 0.0f );
vTexCoords[8] = vProjCoord + float4( fTexelSize, fTexelSize, 0.0f, 0.0f );

// Sample each of them checking whether the pixel under test is shadowed or not
for( int j = 0; j < 9; j++ )
{
float A = tex2Dproj( ShadowSampler, vTexCoords[j] ).r;
float B = vProjCoord.z - 0.0001f;

// Texel is shadowed
fShadowTerm += A < B ? 0.1f : 1.0f;
}

// Get the average
return fShadowTerm = fShadowTerm / 9.0f;
};

...
float4 posInShadow = mul( float4(vWorldPos,1), matTexture );
float ShadowTerm = ShadowPCF(posInShadow);
...
[/code]

Hope somebody will help me ;) One day more on this and i'm gonna explode :P.

Thanks.

Share this post


Link to post
Share on other sites
try using a R32G32 format for your VSM's.

In your PCF prpoblem, i see this

// Output the transformed position
OUT.vPosition = mul( worldPos, matLightViewProj );

// Output the scene depth
OUT.fDepth = OUT.vPosition.z;

return OUT;

you should divide z by w to put it into projected space. At least, that is what is normally done. You didnt post the entire shader, so its just a guess.

OUT.fDepth = OUT.vPosition.z/OUT.vPosition.w;

Or, you can let the hardware do it for you and access the z component in your pixel shader without passing the depth in an extra parameter.


Share this post


Link to post
Share on other sites
[quote name='smasherprog' timestamp='1298136161' post='4776352']
try using a R32G32 format for your VSM's.
[/quote]

Tried it, but shadow look even worse. [url="http://img545.imageshack.us/i/g32r32f.png/"]Pic![/url]

[quote name='smasherprog' timestamp='1298136161' post='4776352']
In your PCF prpoblem, i see this

// Output the transformed position
OUT.vPosition = mul( worldPos, matLightViewProj );

// Output the scene depth
OUT.fDepth = OUT.vPosition.z;

return OUT;

you should divide z by w to put it into projected space. At least, that is what is normally done. You didnt post the entire shader, so its just a guess.

OUT.fDepth = OUT.vPosition.z/OUT.vPosition.w;

Or, you can let the hardware do it for you and access the z component in your pixel shader without passing the depth in an extra parameter.

[/quote]

I tried:
OUT.fDepth = OUT.vPosition.z/OUT.vPosition.w;

But then, scene is unshadowed. Storing only .z component i saw in this tut: http://www.gamedev.net/page/resources/_/reference/programming/special-effects/shadows/soft-edged-shadows-r2193

And that's whole shader. Only:
matLightViewProj - View*Proj Light Matrix
matTexture - matLightViewProj * matTexAdjency
[code]
float fTexOffs = 0.5 + (0.5 / 512.0f);
matTexAdj = D3DXMATRIX( 0.5f, 0.0f, 0.0f, 0.0f,
0.0f, -0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
fTexOffs, fTexOffs, -0.05f, 1.0f );
[/code]
vWorldPos - position from deferred position texture

Share this post


Link to post
Share on other sites

This topic is 2487 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