From 28bc8c79e75dd0fbc60d57586b82de89523ee5f8 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 27 Aug 2020 14:46:20 -0700 Subject: [PATCH] basic directional light shadow mapping --- Effects/DeferredPBREffect.cs | 10 ++++++++ Effects/FXB/DeferredPBREffect.fxb | Bin 53400 -> 54108 bytes Effects/FXB/SimpleDepthEffect.fxb | Bin 624 -> 1008 bytes Effects/HLSL/DeferredPBREffect.fx | 37 +++++++++++++++++++++++++----- Effects/HLSL/SimpleDepthEffect.fx | 14 ++++++++++- Effects/SimpleDepthEffect.cs | 11 +++++++++ Lights/DirectionalLight.cs | 2 +- Renderer.cs | 36 +++++++++++++++++++---------- 8 files changed, 90 insertions(+), 20 deletions(-) diff --git a/Effects/DeferredPBREffect.cs b/Effects/DeferredPBREffect.cs index 97c8615..8b76aca 100644 --- a/Effects/DeferredPBREffect.cs +++ b/Effects/DeferredPBREffect.cs @@ -9,8 +9,11 @@ namespace Kav EffectParameter gAlbedoParam; EffectParameter gNormalParam; EffectParameter gMetallicRoughnessParam; + EffectParameter shadowMapParam; EffectParameter eyePositionParam; + EffectParameter lightSpaceMatrixParam; + PointLightCollection pointLightCollection; DirectionalLightCollection directionalLightCollection; @@ -18,8 +21,10 @@ namespace Kav public Texture2D GAlbedo { get; set; } public Texture2D GNormal { get; set; } public Texture2D GMetallicRoughness { get; set; } + public Texture2D ShadowMap { get; set; } public Vector3 EyePosition { get; set; } + public Matrix LightSpaceMatrix { get; set; } public int MaxPointLights { get; } = 64; @@ -95,8 +100,10 @@ namespace Kav gAlbedoParam.SetValue(GAlbedo); gNormalParam.SetValue(GNormal); gMetallicRoughnessParam.SetValue(GMetallicRoughness); + shadowMapParam.SetValue(ShadowMap); eyePositionParam.SetValue(EyePosition); + lightSpaceMatrixParam.SetValue(LightSpaceMatrix); } void CacheEffectParameters() @@ -105,8 +112,11 @@ namespace Kav gAlbedoParam = Parameters["gAlbedo"]; gNormalParam = Parameters["gNormal"]; gMetallicRoughnessParam = Parameters["gMetallicRoughness"]; + shadowMapParam = Parameters["shadowMap"]; eyePositionParam = Parameters["EyePosition"]; + + lightSpaceMatrixParam = Parameters["LightSpaceMatrix"]; } } } diff --git a/Effects/FXB/DeferredPBREffect.fxb b/Effects/FXB/DeferredPBREffect.fxb index 10298d5149531440477ff239977961028697e518..7bb87291b73782956945627126e1d62215f198ce 100644 GIT binary patch literal 54108 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 Tdst^alLzaK>Rh!xjr#upzD>+; literal 53400 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 mduF_0ZDGxdr|93;I9Z!$+J3gl!}!=6-L~Dk zaO|7Yp?hVw#*RA>oJo0#jXX(5Q4%Y_1G_n7BB}kLqa{FKG0l&Plf%8jU$CFh2jzdmP8DWd zA`wKjiuYth(JU&6a{cgV14UabL@cR?wHWtCjr~SZRGrq)9l4#cwSB&0om6TStJZC{ z?V(k6`<~MSC>3{0;_Xau-T5HZN5V}!3nV7E6(2lwk5|mv7 zq$`lbp-hJVKmcP$OipCF%h)j4o>?^lXg(0}H!v`$OkiPfSir&{x`2~`ff?wE2Mi2P cfZ|V}d?qlT5zc1;^O@j$4lth?$OqX307_0K`Tzg` diff --git a/Effects/HLSL/DeferredPBREffect.fx b/Effects/HLSL/DeferredPBREffect.fx index a49f27a..05a3df7 100644 --- a/Effects/HLSL/DeferredPBREffect.fx +++ b/Effects/HLSL/DeferredPBREffect.fx @@ -8,6 +8,7 @@ DECLARE_TEXTURE(gPosition, 0); DECLARE_TEXTURE(gAlbedo, 1); DECLARE_TEXTURE(gNormal, 2); DECLARE_TEXTURE(gMetallicRoughness, 3); +DECLARE_TEXTURE(shadowMap, 4); // TODO: one map per directional light BEGIN_CONSTANTS @@ -21,6 +22,8 @@ BEGIN_CONSTANTS MATRIX_CONSTANTS + float4x4 LightSpaceMatrix _ps(c137) _cb(c137); + END_CONSTANTS struct PixelInput @@ -71,6 +74,24 @@ float GeometrySmith(float3 N, float3 V, float3 L, float roughness) return ggx1 * ggx2; } +float ComputeShadow(float4 positionLightSpace) +{ + float bias = 0.01; + + // maps to [-1, 1] + float3 projectionCoords = positionLightSpace.xyz / positionLightSpace.w; + + // maps to [0, 1] + projectionCoords = (projectionCoords * 0.5) + 0.5; + + float closestDepth = SAMPLE_TEXTURE(shadowMap, projectionCoords.xy).r; + float currentDepth = projectionCoords.z; + + float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0; + + return shadow; +} + float3 ComputeLight( float3 lightDir, float3 radiance, @@ -79,7 +100,8 @@ float3 ComputeLight( float3 N, float3 albedo, float metallic, - float roughness + float roughness, + float shadow ) { float3 L = normalize(lightDir); float3 H = normalize(V + L); @@ -98,7 +120,7 @@ float3 ComputeLight( kD *= 1.0 - metallic; float NdotL = max(dot(N, L), 0.0); - return (kD * albedo / PI + specular) * radiance * NdotL; + return (kD * albedo / PI + specular) * radiance * NdotL * shadow; } float4 ComputeColor( @@ -108,6 +130,9 @@ float4 ComputeColor( float metallic, float roughness ) { + float4 positionLightSpace = mul(float4(worldPosition, 1.0), LightSpaceMatrix); + float shadow = ComputeShadow(positionLightSpace); + float3 V = normalize(EyePosition - worldPosition); float3 N = normalize(worldNormal); @@ -124,7 +149,7 @@ float4 ComputeColor( float attenuation = 1.0 / (distance * distance); float3 radiance = PointLightColors[i] * attenuation; - Lo += ComputeLight(lightDir, radiance, F0, V, N, albedo, metallic, roughness); + Lo += ComputeLight(lightDir, radiance, F0, V, N, albedo, metallic, roughness, 1.0); } // directional light @@ -133,7 +158,7 @@ float4 ComputeColor( float3 lightDir = DirectionalLightDirections[i]; float3 radiance = DirectionalLightColors[i]; - Lo += ComputeLight(lightDir, radiance, F0, V, N, albedo, metallic, roughness); + Lo += ComputeLight(lightDir, radiance, F0, V, N, albedo, metallic, roughness, (1.0 - shadow)); } float3 ambient = float3(0.03, 0.03, 0.03) * albedo; // * AO; @@ -148,13 +173,13 @@ float4 ComputeColor( float4 main_ps(PixelInput input) : SV_TARGET0 { - float3 fragPosition = SAMPLE_TEXTURE(gPosition, input.TexCoord).rgb; + float3 worldPosition = SAMPLE_TEXTURE(gPosition, input.TexCoord).rgb; float3 normal = SAMPLE_TEXTURE(gNormal, input.TexCoord).xyz; float3 albedo = SAMPLE_TEXTURE(gAlbedo, input.TexCoord).rgb; float2 metallicRoughness = SAMPLE_TEXTURE(gMetallicRoughness, input.TexCoord).rg; return ComputeColor( - fragPosition, + worldPosition, normal, albedo, metallicRoughness.r, diff --git a/Effects/HLSL/SimpleDepthEffect.fx b/Effects/HLSL/SimpleDepthEffect.fx index 8b19a4e..787ea2a 100644 --- a/Effects/HLSL/SimpleDepthEffect.fx +++ b/Effects/HLSL/SimpleDepthEffect.fx @@ -3,6 +3,8 @@ BEGIN_CONSTANTS float4x4 ModelViewProjection _vs(c0) _cb(c0); + float near _vs(c4) _cb(c4); + float far _vs(c5) _cb(c5); MATRIX_CONSTANTS @@ -16,21 +18,31 @@ struct VertexShaderInput struct VertexShaderOutput { float4 Position : SV_Position; + float Depth : TEXCOORD0; }; VertexShaderOutput main_vs(VertexShaderInput input) { VertexShaderOutput output; - output.Position = mul(float4(input.Position.xyz, 1.0), ModelViewProjection); + output.Position = mul(input.Position, ModelViewProjection); + + output.Depth = output.Position.z / output.Position.w; + output.Depth = (output.Depth * 0.5) + 0.5; return output; } +float4 main_ps(VertexShaderOutput input) : SV_TARGET0 +{ + return float4(input.Depth, 0.0, 0.0, 0.0); +} + Technique SimpleDepth { Pass { VertexShader = compile vs_3_0 main_vs(); + PixelShader = compile ps_3_0 main_ps(); } } diff --git a/Effects/SimpleDepthEffect.cs b/Effects/SimpleDepthEffect.cs index f68f513..c821a6a 100644 --- a/Effects/SimpleDepthEffect.cs +++ b/Effects/SimpleDepthEffect.cs @@ -6,6 +6,8 @@ namespace Kav public class SimpleDepthEffect : Effect { EffectParameter modelViewProjectionParam; + EffectParameter nearParam; + EffectParameter farParam; Matrix model; Matrix view; @@ -42,6 +44,10 @@ namespace Kav dirtyFlags |= EffectDirtyFlags.WorldViewProj; } } + + public float Near { get; set; } + public float Far { get; set; } + public SimpleDepthEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.SimpleDepthEffect) { CacheEffectParameters(); @@ -58,11 +64,16 @@ namespace Kav dirtyFlags &= ~EffectDirtyFlags.WorldViewProj; } + + nearParam.SetValue(Near); + farParam.SetValue(Far); } private void CacheEffectParameters() { modelViewProjectionParam = Parameters["ModelViewProjection"]; + nearParam = Parameters["near"]; + farParam = Parameters["far"]; } } } diff --git a/Lights/DirectionalLight.cs b/Lights/DirectionalLight.cs index 31ca4fd..a22ab33 100644 --- a/Lights/DirectionalLight.cs +++ b/Lights/DirectionalLight.cs @@ -12,7 +12,7 @@ namespace Kav { get { - return Matrix.CreateLookAt(-Direction * 100f, Vector3.Zero, Vector3.Up); + return Matrix.CreateLookAt(Direction * 100f, Vector3.Zero, Vector3.Up); } } diff --git a/Renderer.cs b/Renderer.cs index c53f855..35f4b7d 100644 --- a/Renderer.cs +++ b/Renderer.cs @@ -36,7 +36,7 @@ namespace Kav renderDimensionsX, renderDimensionsY, false, - SurfaceFormat.HalfSingle, // unused + SurfaceFormat.Single, DepthFormat.Depth24 ); @@ -105,6 +105,13 @@ namespace Kav IEnumerable pointLights, IEnumerable directionalLights ) { + foreach (var directionalLight in directionalLights) + { + DepthRender(modelTransforms, directionalLight); + DeferredPBREffect.LightSpaceMatrix = directionalLight.View * directionalLight.Projection; + break; // FIXME: this is a kludge + } + GraphicsDevice.SetRenderTargets(GBuffer); GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1f, 0); GraphicsDevice.DepthStencilState = DepthStencilState.Default; @@ -150,6 +157,7 @@ namespace Kav DeferredPBREffect.GAlbedo = gAlbedo; DeferredPBREffect.GNormal = gNormal; DeferredPBREffect.GMetallicRoughness = gMetallicRoughness; + DeferredPBREffect.ShadowMap = DepthRenderTarget; DeferredPBREffect.EyePosition = Matrix.Invert(camera.View).Translation; int i = 0; @@ -173,23 +181,18 @@ namespace Kav SpriteBatch.End(); } - public void Render( - Camera camera, - IEnumerable<(Model, Matrix)> modelTransforms, - IEnumerable pointLights, - IEnumerable directionalLights - ) { - Render(camera.View, camera.Projection, modelTransforms, pointLights, directionalLights); - } - // for shadow mapping public void DepthRender(IEnumerable<(Model, Matrix)> modelTransforms, DirectionalLight directionalLight) { GraphicsDevice.SetRenderTarget(DepthRenderTarget); - GraphicsDevice.Clear(ClearOptions.DepthBuffer, Color.Black, 1, 0); - + GraphicsDevice.Clear(Color.White); + GraphicsDevice.DepthStencilState = DepthStencilState.Default; + GraphicsDevice.BlendState = BlendState.Opaque; + SimpleDepthEffect.View = directionalLight.View; SimpleDepthEffect.Projection = directionalLight.Projection; + SimpleDepthEffect.Near = 0.1f; // FIXME: this is a kludge + SimpleDepthEffect.Far = 200f; foreach (var (model, transform) in modelTransforms) { @@ -220,6 +223,15 @@ namespace Kav } } + public void Render( + Camera camera, + IEnumerable<(Model, Matrix)> modelTransforms, + IEnumerable pointLights, + IEnumerable directionalLights + ) { + Render(camera.View, camera.Projection, modelTransforms, pointLights, directionalLights); + } + private void Render( Matrix view, Matrix projection,