Ok - I Got you now..
In order to fix this issue the IntegratedPSSM3 SubRenderState should apply the shadow factor only on the shadow caster lights diffuse/specular terms.
When using per-vertex lighting (I.E the FFP) the lighting are computed on the VS stage and since the shadowing is done in the PS stage separating the lighting terms requires splitting the output vertex shader color to multiple channels - so I think we'll skip this one.
On per-pixel lighting models this is simple task, but it require the IntegratedPSSM3 SubRenderState to be aware of the internal function invocation order of the lighting SubRenderState.
I thought about some kind of callback mechanism that will allow such tasks to be done without deep coupling of the stages, but unfortunately such a mechanism still lay on the paper...
This is output FS of the ground plane when using per pixel lighting and two lights with shadow on:
Code: Select all
//-----------------------------------------------------------------------------
// Function Name: main
// Function Desc: Pixel Program Entry point
//-----------------------------------------------------------------------------
void main
(
in float3 iTexcoord3_0 : TEXCOORD0,
in float3 iTexcoord3_1 : TEXCOORD1,
in float2 iTexcoord2_2 : TEXCOORD2,
in float iTexcoord1_3 : TEXCOORD3,
in float4 iTexcoord4_4 : TEXCOORD4,
in float4 iTexcoord4_5 : TEXCOORD5,
in float4 iTexcoord4_6 : TEXCOORD6,
out float4 oColor_0 : COLOR
)
{
float4 lLocalParam_0;
float4 lLocalParam_1;
float4 lPerPixelDiffuse;
float4 texel;
float4 source1;
float4 source2;
float lShadowFactor;
FFP_Construct(1.0, 1.0, 1.0, 1.0, lLocalParam_0);
FFP_Construct(0.0, 0.0, 0.0, 0.0, lLocalParam_1);
FFP_Assign(lLocalParam_0, oColor_0);
FFP_Assign(derived_scene_colour, lPerPixelDiffuse);
SGX_Light_Directional_Diffuse(iTexcoord3_0, light_direction_view_space0.xyz, derived_light_diffuse1.xyz, lPerPixelDiffuse.xyz, lPerPixelDiffuse.xyz);
SGX_Light_Spot_Diffuse(iTexcoord3_0, iTexcoord3_1, light_position_view_space2.xyz, light_direction_view_space3.xyz, light_attenuation4, spotlight_params0, derived_light_diffuse5.xyz, lPerPixelDiffuse.xyz, lPerPixelDiffuse.xyz);
FFP_Assign(lPerPixelDiffuse, lLocalParam_0);
FFP_Assign(lLocalParam_0, oColor_0);
SGX_ComputeShadowFactor_PSSM3(iTexcoord1_3, pssm_split_points6, iTexcoord4_4, iTexcoord4_5, iTexcoord4_6, shadow_map1, shadow_map2, shadow_map3, inv_shadow_texture_size7, inv_shadow_texture_size8, inv_shadow_texture_size9, lShadowFactor);
SGX_ApplyShadowFactor_Diffuse(derived_scene_colour, lLocalParam_0, lShadowFactor, lLocalParam_0);
SGX_ModulateScalar(lShadowFactor, lLocalParam_1, lLocalParam_1);
FFP_Assign(lLocalParam_0, oColor_0);
FFP_SampleTexture(gTextureSampler0, iTexcoord2_2, texel);
FFP_Assign(texel, source1);
FFP_Assign(lLocalParam_0, source2);
FFP_Modulate(source1, source2, oColor_0);
FFP_Add(oColor_0.xyz, lLocalParam_1.xyz, oColor_0.xyz);
}
The right shader that will do what you are looking for is
Code: Select all
//-----------------------------------------------------------------------------
// Function Name: main
// Function Desc: Pixel Program Entry point
//-----------------------------------------------------------------------------
void main
(
in float3 iTexcoord3_0 : TEXCOORD0,
in float3 iTexcoord3_1 : TEXCOORD1,
in float2 iTexcoord2_2 : TEXCOORD2,
in float iTexcoord1_3 : TEXCOORD3,
in float4 iTexcoord4_4 : TEXCOORD4,
in float4 iTexcoord4_5 : TEXCOORD5,
in float4 iTexcoord4_6 : TEXCOORD6,
out float4 oColor_0 : COLOR
)
{
float4 lLocalParam_0;
float4 lLocalParam_1;
float4 lPerPixelDiffuse;
float4 texel;
float4 source1;
float4 source2;
float lShadowFactor;
FFP_Construct(1.0, 1.0, 1.0, 1.0, lLocalParam_0);
FFP_Construct(0.0, 0.0, 0.0, 0.0, lLocalParam_1);
FFP_Assign(lLocalParam_0, oColor_0);
SGX_ComputeShadowFactor_PSSM3(iTexcoord1_3, pssm_split_points6, iTexcoord4_4, iTexcoord4_5, iTexcoord4_6, shadow_map1, shadow_map2, shadow_map3, inv_shadow_texture_size7, inv_shadow_texture_size8, inv_shadow_texture_size9, lShadowFactor);
FFP_Assign(derived_scene_colour, lPerPixelDiffuse);
SGX_Light_Directional_Diffuse(iTexcoord3_0, light_direction_view_space0.xyz, derived_light_diffuse1.xyz, lPerPixelDiffuse.xyz, lPerPixelDiffuse.xyz);
SGX_ApplyShadowFactor_Diffuse(derived_scene_colour, lPerPixelDiffuse, lShadowFactor, lPerPixelDiffuse);
SGX_Light_Spot_Diffuse(iTexcoord3_0, iTexcoord3_1, light_position_view_space2.xyz, light_direction_view_space3.xyz, light_attenuation4, spotlight_params0, derived_light_diffuse5.xyz, lPerPixelDiffuse.xyz, lPerPixelDiffuse.xyz);
FFP_Assign(lPerPixelDiffuse, lLocalParam_0);
FFP_Assign(lLocalParam_0, oColor_0);
SGX_ModulateScalar(lShadowFactor, lLocalParam_1, lLocalParam_1);
FFP_Assign(lLocalParam_0, oColor_0);
FFP_SampleTexture(gTextureSampler0, iTexcoord2_2, texel);
FFP_Assign(texel, source1);
FFP_Assign(lLocalParam_0, source2);
FFP_Modulate(source1, source2, oColor_0);
FFP_Add(oColor_0.xyz, lLocalParam_1.xyz, oColor_0.xyz);
}
Another solution I can think about is to create explicit local shadow coeff parameter for each light that will be initialized to 1 by default, then force each lighting sub render to take this factor into account when doing the lighting calculations..
Any other ideas/solutions are welcome - I hope I can get to it since I'm quite busy with my start-up lately...
