На первом изображении показан шейдер перед попыткой выполнения PCF. Это шейдер, который мы используем уже некоторое время, и он в целом работает, за исключением явно неровных краев по краям уровня и некоторой неправильной штриховки на пне.

На втором изображении показано, что происходит при попытке использовать PCF. Я не верю, что это функция PCF, поскольку она взята непосредственно из рабочего примера, но я определенно могу ошибаться.

Вот мой код шейдера (HLSL):
Код: Выделить всё
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// VARIABLES
////////////////////////////////////////////////////////////////////////////////////////////////////////////
matrix World;
matrix WorldViewProjection;
float3 AmbientLightColor;
////Be sure this matches the define in SolariDefines.cs
//static const int MAX_POINT_LIGHTS = 8;
//int PointLightCount;
//float3 PointLightPosition[MAX_POINT_LIGHTS];
//float PointLightRange[MAX_POINT_LIGHTS];
//float3 PointLightColor[MAX_POINT_LIGHTS];
//
float3 DirectionalLight;
float3 DirectionalLightColor;
float DirectionalLightIntensity;
float4x4 xLightsWorldViewProjection;
texture Texture;
sampler TextureSampler = sampler_state
{
texture = ;
magfilter = LINEAR;
minfilter = LINEAR;
mipfilter = LINEAR;
AddressU = mirror;
AddressV = mirror;
};
texture Normals;
sampler NormalMapSampler = sampler_state
{
texture = (Normals);
MagFilter = LINEAR;
MinFilter = LINEAR;
Mipfilter = LINEAR;
};
texture ShadowMap;
sampler ShadowMapSampler = sampler_state
{
texture = ;
magfilter = LINEAR;
minfilter = LINEAR;
mipfilter = LINEAR;
AddressU = clamp;
AddressV = clamp;
};
float DepthBias;
float ShadowMapSize = 2048;
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// STRUCTS
////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct VertexShaderInput
{
float4 Position : POSITION0;
float3 Normal: NORMAL0;
float2 texCoord : TEXCOORD0;
float3 Binormal : BINORMAL0;
float3 Tangent : TANGENT0;
};
struct SMapVertexToPixel
{
float4 Position : POSITION;
float Depth : TEXCOORD0;
};
struct SMapPixelToFrame
{
float4 Color : COLOR0;
};
struct SSceneVertexToPixel
{
float4 Position : POSITION;
float4 Pos2DAsSeenByLight : TEXCOORD0;
float2 TexCoords : TEXCOORD1;
float3 Normal : TEXCOORD2;
float4 Position3D : TEXCOORD3;
float3x3 WorldToTangentSpace : TEXCOORD4;
};
struct SScenePixelToFrame
{
float4 Color : COLOR0;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// HELPER FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////////////////////////
float GetVariableBias(float nDotL)
{
return clamp( 0.005 * tan(acos(nDotL)), 0, DepthBias );
}
float CalcShadowTermPCF(float linearDepthLV, float ndotl, float2 shadowTexCoord)
{
float lightTerm = 0;
float2 fractionals = frac(ShadowMapSize * shadowTexCoord);
float size = 1.0f / ShadowMapSize;
float variableBias = GetVariableBias(ndotl);
float testDepth = linearDepthLV - variableBias;
//Center
lightTerm = (linearDepthLV < tex2D(ShadowMapSampler, shadowTexCoord).r);
//Right
lightTerm += (testDepth < tex2D(ShadowMapSampler, shadowTexCoord + float2(size, 0)).r) * fractionals.x;
//Left
lightTerm += (testDepth < tex2D(ShadowMapSampler, shadowTexCoord + float2(-size, 0)).r) * (1 - fractionals.x);
//Top
lightTerm += (testDepth < tex2D(ShadowMapSampler, shadowTexCoord + float2(0, size)).r) * fractionals.y;
//Bottom
lightTerm += (testDepth < tex2D(ShadowMapSampler, shadowTexCoord + float2(0, -size)).r) * (1 - fractionals.y);
lightTerm /= 3;
return lightTerm;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// VERTEX / PIXEL FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////////////////////////
SMapVertexToPixel ShadowMapVertexShader(VertexShaderInput input)
{
SMapVertexToPixel Output = (SMapVertexToPixel)0;
Output.Position = mul(input.Position, xLightsWorldViewProjection);
Output.Depth = Output.Position.z / Output.Position.w;
return Output;
}
SMapPixelToFrame ShadowMapPixelShader(SMapVertexToPixel PSIn)
{
SMapPixelToFrame Output = (SMapPixelToFrame)0;
Output.Color = float4( PSIn.Depth, PSIn.Depth, PSIn.Depth, PSIn.Depth );
return Output;
}
SSceneVertexToPixel ShadowedSceneVertexShader(VertexShaderInput input)
{
SSceneVertexToPixel Output = (SSceneVertexToPixel)0;
Output.Position = mul(input.Position, WorldViewProjection);
Output.Pos2DAsSeenByLight = mul(input.Position, xLightsWorldViewProjection);
Output.Normal = normalize(mul(input.Normal, (float3x3)World));
Output.Position3D = mul(input.Position, World);
Output.TexCoords = input.texCoord;
Output.WorldToTangentSpace[0] = mul(normalize(input.Tangent), World);
Output.WorldToTangentSpace[1] = mul(normalize(input.Binormal), World);
Output.WorldToTangentSpace[2] = mul(normalize(input.Normal), World);
return Output;
}
SScenePixelToFrame ShadowedScenePixelShader(SSceneVertexToPixel PSIn)
{
SScenePixelToFrame Output = (SScenePixelToFrame)0;
float2 shadowMapTexCoords;
shadowMapTexCoords[0] = PSIn.Pos2DAsSeenByLight.x / PSIn.Pos2DAsSeenByLight.w / 2.0f + 0.5f;
shadowMapTexCoords[1] = -PSIn.Pos2DAsSeenByLight.y / PSIn.Pos2DAsSeenByLight.w / 2.0f + 0.5f;
float diffuseLightingFactor = 0;
float3 normalMap = 2.0 *(tex2D(NormalMapSampler, PSIn.TexCoords)) - 1.0;
float3 normal = normalize(mul(normalMap, PSIn.WorldToTangentSpace));
float depthStoredInShadowMap = tex2D(ShadowMapSampler, shadowMapTexCoords).r;
float realDistance = PSIn.Pos2DAsSeenByLight.z / PSIn.Pos2DAsSeenByLight.w;
float nDotL = dot(-DirectionalLight, normal);
float variableBias = GetVariableBias( nDotL );
if ( (realDistance - variableBias)
Подробнее здесь: [url]https://stackoverflow.com/questions/79148238/seeing-odd-behavior-attempting-to-add-pcf-to-shadow-map-shader[/url]