Недавно я реализовал тени в своем проекте местности, используя фильтрацию PCF, однако тени на склонах местности выглядят некорректно, как вы можете видеть ниже:
Как я могу удалить артефакты, вызванные на склонах местности? Быстрый поиск предлагает реализовать уклон на основе уклона, но как мне его рассчитать?
Вот мой пиксельный шейдер:
Texture2D shadowMap : register(t0);
SamplerComparisonState SampleTypeCmp : register(s0);
cbuffer SPerLightCB : register(b0)
{
float4 ambientColour;
float4 diffuseColour;
};
cbuffer SPerLightPosCB : register(b1)
{
float3 lightPos;
float padding;
};
struct PixelIn
{
float4 Pos : SV_POSITION;
float4 WPos : TEXCOORD0;
float4 LPos : TEXCOORD1;
float3 Normal : NORMAL;
};
float2 texOffset(int u, int v)
{
return float2(u * 1.0f / 1024.0f, v * 1.0f / 1024.0f);
}
float4 main(PixelIn pin) : SV_Target
{
//re-homogenize position after interpolation
pin.LPos.xyz /= pin.LPos.w;
//if position is not visible to the light - dont illuminate it
//results in hard light frustum
if (pin.LPos.x < -1.0f || pin.LPos.x > 1.0f ||
pin.LPos.y < -1.0f || pin.LPos.y > 1.0f ||
pin.LPos.z < 0.0f || pin.LPos.z > 1.0f)
{
return ambientColour;
}
//transform clip space coords to texture space coords (-1:1 to 0:1)
pin.LPos.x = pin.LPos.x / 2 + 0.5;
pin.LPos.y = pin.LPos.y / -2 + 0.5;
pin.LPos.z -= 0.001f; //apply bias
//PCF Sampling
float sum = 0.0f;
float x, y;
//perform PCF filtering
for (y = -1.5; y <= 1.5; y += 1.0)
{
for (x = -1.5; x <= 1.5; x += 1.0)
{
sum += shadowMap.SampleCmpLevelZero(SampleTypeCmp, pin.LPos.xy + texOffset(x, y), pin.LPos.z);
}
}
float shadowFactor = sum / 16.0;
//calculate ilumination
float3 L = normalize(lightPos - pin.WPos.xyz);
float ndotl = dot(normalize(pin.Normal), L);
return ambientColour + shadowFactor * diffuseColour * ndotl;
}
Задача ещё не решена.
Других решений пока нет …