Advertisement

Shadow problem in directx11

Started by December 07, 2024 05:44 PM
10 comments, last by Sekt4nt 1 day, 20 hours ago

As you see, instead of fabulous shadow from my model, I see that black line, could some one pls explain why that happened ? Kind regards

************ SHADOW VERTEX SHADER ***************

cbuffer WorldMatrix : register(b2)
{
float4x4 world;
};
cbuffer LightMatrix : register(b3)
{
float4x4 lightViewProjection;
};
struct VS_INPUT
{
float4 position : POSITION;
};
struct VS_OUTPUT
{
float4 position : SV_POSITION;
};
VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT output;
float4 worldPos = mul(input.position, world);
output.position = mul(worldPos, lightViewProjection);
return output;
}

****************** LIGHT PIXEL SHADER ******************


struct Light
{
int Type;
float3 Position;
float3 Direction;
float3 Color;
float Intensity;
float Range;
float SpotAngle;
};
struct DirectionalLight
{
float3 Direction;
float Intensity;
float3 Color;
float Padding;
};
StructuredBuffer<Light> Lights : register(t4);
cbuffer LightInfo : register(b0)
{
int LightCount;
int align[3];
};
cbuffer LightMatrix : register(b3)
{
matrix lightViewProj;
};
cbuffer DirectionalLight : register(b2)
{
DirectionalLight directionalLight;
};
float3 CalculateDirectionalLight(DirectionalLight directionalLight, float3 normal)
{
float3 lightDir = normalize(-directionalLight.Direction);
float diff = max(dot(normal, lightDir), 0.0);
return directionalLight.Color * diff * directionalLight.Intensity;
}
float3 CalculatePointLight(Light light, float3 worldPos, float3 normal)
{
float3 lightDir = light.Position - worldPos;
float distance = length(lightDir);
lightDir = normalize(lightDir);
float diff = max(dot(normal, lightDir), 0.0);
float attenuation = 1.0 / (distance * distance + 1e-4);
if (distance < light.Range)
{
return light.Color * diff * attenuation * light.Intensity;
}
return float3(0, 0, 0);
}
float3 CalculateSpotLight(Light light, float3 worldPos, float3 normal)
{
float3 lightDir = light.Position - worldPos;
float distance = length(lightDir);
lightDir = normalize(lightDir);
float theta = dot(lightDir, normalize(-light.Direction));
float epsilon = cos(radians(light.SpotAngle) * 0.5);
if (theta > epsilon && distance < light.Range)
{
float diff = max(dot(normal, lightDir), 0.0);
float attenuation = 1.0 / (distance * distance + 1e-4);
float spotEffect = smoothstep(epsilon, 1.0, theta);
return light.Color * diff * attenuation * spotEffect * light.Intensity;
}
return float3(0, 0, 0);
}
Texture2D DiffuseTexture : register(t0);
Texture2D NormalTexture : register(t1);
Texture2D PositionTexture : register(t2);
Texture2D ShadowMap : register(t5);
SamplerState samplerState : register(s0);
struct PSInput
{
float4 Position : SV_Position;
float2 TexCoord : TEXCOORD;
};
float ShadowFactor(float3 worldPos)
{
float4 lightPos = mul(float4(worldPos, 1.0f), lightViewProj);
lightPos /= lightPos.w;
float2 shadowUV = lightPos.xy * 0.5f + 0.5f;
float shadowDepth = ShadowMap.Sample(samplerState, shadowUV).r;
float bias = 0.005f;
return (lightPos.z - bias > shadowDepth) ? 0.0f : 1.0f;
}
float4 main(PSInput input) : SV_Target
{
float4 diffuse = DiffuseTexture.Sample(samplerState, input.TexCoord);
float3 normal = normalize(NormalTexture.Sample(samplerState, input.TexCoord).xyz);
float3 worldPos = PositionTexture.Sample(samplerState, input.TexCoord).xyz;
float3 finalColor = float3(1.0f, 1.0f, 1.0f);
finalColor += CalculateDirectionalLight(directionalLight, normal) * ShadowFactor(worldPos);
for (int i = 0; i < LightCount; ++i)
{
Light light = Lights[i];
if (light.Type == 0)
{
finalColor += CalculatePointLight(light, worldPos, normal);
}
else if (light.Type == 1)
{
finalColor += CalculateSpotLight(light, worldPos, normal);
}
}
return float4(finalColor * diffuse.rgb, diffuse.a);
}


Directional light data

void TDXRenderDevice::SetDirectionalLight(TVector3 direction, TVector3 color, float intensity)
{
DirectionalLightCBS directionalLight = { direction, intensity, color };
m_TDXBufferManager.UpdateDynamicConstantBuffer(DIRECTIONAL_LIGHT_CONSTANT_BUFFER, &directionalLight, sizeof(DirectionalLightCBS), m_pDeviceContext.Get());
DirectX::XMVECTOR lightDirection = DirectX::XMVector3Normalize(DirectX::XMVectorSet(direction.x, direction.y, direction.z, 0.0f));
DirectX::XMVECTOR lightTarget = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
float distance = 500.0f;
DirectX::XMVECTOR lightPosition = DirectX::XMVectorSubtract(lightTarget, DirectX::XMVectorScale(lightDirection, distance));
DirectX::XMVECTOR lightUp = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
DirectX::XMMATRIX lightView = DirectX::XMMatrixLookAtLH(lightPosition, lightTarget, lightUp);
float nearPlane = 0.1f;
float farPlane = 1000.0f;
float shadowMapSize = 1024.0f;
DirectX::XMMATRIX lightProjection = DirectX::XMMatrixOrthographicLH(shadowMapSize, shadowMapSize, nearPlane, farPlane);
MatrixCBS lightViewProj = { lightView * lightProjection };
m_TDXBufferManager.UpdateDynamicConstantBuffer(LIGHT_VIEW_PROJ_CONSTANT_BUFFER, &lightViewProj, sizeof(MatrixCBS), m_pDeviceContext.Get());
}



None


I have that on input of Shadow Vertex shader, is that normal ?

None

Advertisement

By the way, I try to implement Directional light

None

I added transpose to matrices and change some light values, got this result but dont see any shadows:





void TDXRenderDevice::SetDirectionalLight(TVector3 direction, TVector3 color, float intensity)
{
   DirectionalLightCBS directionalLight = { direction, intensity, color  };
   m_TDXBufferManager.UpdateDynamicConstantBuffer(DIRECTIONAL_LIGHT_CONSTANT_BUFFER, &directionalLight, sizeof(DirectionalLightCBS), m_pDeviceContext.Get());
   DirectX::XMVECTOR lightDirection = DirectX::XMVector3Normalize(DirectX::XMVectorSet(direction.x, direction.y, direction.z, 0.0f));
   DirectX::XMVECTOR lightTarget = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
   float distance = 500.0f;
   DirectX::XMVECTOR lightPosition = DirectX::XMVectorSet(40.0f, 40.0f, 40.0f, 1.0f);
   DirectX::XMVECTOR lightUp = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
   DirectX::XMMATRIX lightView = DirectX::XMMatrixLookAtLH(lightPosition, lightTarget, lightUp);
   float nearPlane = 0.1f;
   float farPlane = 1000.0f;
   float shadowMapSize = 40.0f;
   DirectX::XMMATRIX lightProjection = DirectX::XMMatrixOrthographicLH(shadowMapSize, shadowMapSize, nearPlane, farPlane);
   MatrixCBS lightViewProj = { DirectX::XMMatrixTranspose(lightView * lightProjection) };
   m_TDXBufferManager.UpdateDynamicConstantBuffer(LIGHT_VIEW_PROJ_CONSTANT_BUFFER, &lightViewProj, sizeof(MatrixCBS), m_pDeviceContext.Get());
}


None

None

I fixed, now shadow shows (depthStencilState was wrong), but know it renders like this






And it depends on window size, if I change it to smaller, thats looks like that



None

Advertisement

None

your slowly getting there! ur about 3 more bugs away from getting it. 🙂

Screenshots look cool btw.

@MitsubishiMagna Thanks, I solved the problem with resizing by added dedicated viewport for shadows. Do you know how to solve position and rotation problem ?

None

None

Advertisement