This is Caelum sample.cg, where in MainFP funcion we calculate the shadow amount per split plane:
Code: Select all
void PssmShadowCasterVP(
float4 position : POSITION,
out float4 oPosition : POSITION,
out float2 oDepth : TEXCOORD0,
uniform float4x4 wvpMat)
{
// this is the view space position
oPosition = mul(wvpMat, position);
// depth info for the fragment.
oDepth.x = oPosition.z;
oDepth.y = oPosition.w;
// clamp z to zero. seem to do the trick. :-/
//oPosition.z = max(oPosition.z, 0);
}
void PssmShadowCasterFP(
float2 depth : TEXCOORD0,
out float4 oColour : COLOR,
uniform float4 pssmSplitPoints)
{
float finalDepth = depth.x / depth.y;
oColour = float4(finalDepth, finalDepth, finalDepth, 1);
}
// Vertex program entry point.
void MainVP(
in float4 iPosition : POSITION,
in float2 iTexCoord : TEXCOORD0,
in float4 iNormal : NORMAL,
uniform float4x4 texWorldViewProjMatrix0,
uniform float4x4 texWorldViewProjMatrix1,
uniform float4x4 texWorldViewProjMatrix2,
uniform float4x4 worldviewproj_matrix,
uniform float4x4 inverse_transpose_worldview_matrix,
out float4 oLightPosition2 : TEXCOORD5,
out float4 oLightPosition1 : TEXCOORD4,
out float4 oLightPosition0 : TEXCOORD3,
out float oSplitPoint : TEXCOORD2,
out float2 oTexCoord : TEXCOORD0,
out float3 oNormal : TEXCOORD1,
out float4 oPosition : POSITION)
{
oPosition = mul(worldviewproj_matrix, iPosition);
oTexCoord = iTexCoord;
oNormal = normalize(mul(inverse_transpose_worldview_matrix, iNormal).xyz);
// Calculate the position of vertex in light space
oSplitPoint = oPosition.z;
oLightPosition0 = mul(texWorldViewProjMatrix0, iPosition);
oLightPosition1 = mul(texWorldViewProjMatrix1, iPosition);
oLightPosition2 = mul(texWorldViewProjMatrix2, iPosition);
}
// Fragment program entry point.
void MainFP(
in float2 iTexcoord : TEXCOORD0,
in float3 iNormal : TEXCOORD1,
in float4 iSplitPoint : TEXCOORD2,
in float4 iLightPosition0 : TEXCOORD3,
in float4 iLightPosition1 : TEXCOORD4,
in float4 iLightPosition2 : TEXCOORD5,
uniform float4 invShadowMapSize0,
uniform float4 invShadowMapSize1,
uniform float4 invShadowMapSize2,
uniform float4 pssmSplitPoints,
uniform sampler2D shadowMap0 : register(s0),
uniform sampler2D shadowMap2 : register(s2),
uniform sampler2D shadowMap1 : register(s1),
uniform sampler mainTexture : register(s3),
uniform float4 light_position_view_space,
uniform float4 derived_light_diffuse_colour,
out float4 oColour : COLOR)
{
// calculate shadow
float shadowing = 1.0f;
float4 splitColour;
if (iSplitPoint <= pssmSplitPoints.y) {
splitColour = float4(0.1, 0, 0, 1);
//here we calculate the shadow amount if the pixel is in the first split plane
shadowing = shadowPCF(shadowMap0, iLightPosition0, invShadowMapSize0.xy);
} else if (iSplitPoint <= pssmSplitPoints.z) {
splitColour = float4(0, 0.1, 0, 1);
//here we calculate the shadow amount if the pixel is in the second split plane
shadowing = shadowPCF(shadowMap1, iLightPosition1, invShadowMapSize1.xy);
} else {
splitColour = float4(0.0, 0.0, 1.0, 1);
//here we calculate the shadow amount if the pixel is in the third split plane
shadowing = shadowPCF(shadowMap2, iLightPosition2, invShadowMapSize2.xy);
}
oColour = float4(0, 0, 0, 0);
float4 baseColour = tex2D(mainTexture, iTexcoord);
baseColour = baseColour*2;
float3 normal = normalize(iNormal);
float diffuse_factor = max(0, dot(float4(normal, 1), light_position_view_space));
float4 light_colour = diffuse_factor * derived_light_diffuse_colour * shadowing;
oColour += baseColour * light_colour;
}
Code: Select all
float shadowPCF(sampler2D shadowMap, float4 shadowMapPos, float2 offset)
{
shadowMapPos = shadowMapPos / shadowMapPos.w;
float2 uv = shadowMapPos.xy;
float3 o = float3(offset, -offset.x) * 0.3f;
// Note: We using 2x2 PCF. Good enough and is alot faster.
float c = (shadowMapPos.z <= tex2D(shadowMap, uv.xy - o.xy).r) ? 1 : 0; // top left
c += (shadowMapPos.z <= tex2D(shadowMap, uv.xy + o.xy).r) ? 1 : 0; // bottom right
c += (shadowMapPos.z <= tex2D(shadowMap, uv.xy + o.zy).r) ? 1 : 0; // bottom left
c += (shadowMapPos.z <= tex2D(shadowMap, uv.xy - o.zy).r) ? 1 : 0; // top right
return c / 4;
}
Code: Select all
//Try to achive soft shadow PCSS + PCF with constant penumbrae
float shadowPCF(sampler2D shadowMap, float4 shadowMapPos, float2 offset)
{
shadowMapPos = shadowMapPos / shadowMapPos.w;
float2 uv = shadowMapPos.xy;
float radius = offset;
float steps = 4;
double stepSize = 2.0 * radius / steps;
uv.xy -= radius.xx;
float total = 0;
for (int x = 0; x < steps; ++x)
for (int y = 0; y < steps; ++y)
total += (shadowMapPos.z <= tex2D(shadowMap, float2(uv.xy + float2(x * stepSize, y * stepSize))).r) ? 1 : 0;
return total / (steps * steps);
}

I can't really figure out where is the issue.. am I doing some errors in how I modify shadowPCF code?
Thank you for any kind of help!