From 7e82f2f32ef039ab1432eb45b2f5fc02fe617e90 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Sun, 20 Sep 2020 20:50:55 -0700 Subject: [PATCH] initial soft shadow implementation --- Effects/DeferredPBR_DirectionalLightEffect.cs | 9 ++ .../DeferredPBR_DirectionalLightEffect.fxb | Bin 6916 -> 11216 bytes .../DeferredPBR_DirectionalLightEffect.fx | 138 +++++++++++++----- Effects/HLSL/Lighting.fxh | 4 +- Effects/HLSL/Macros.fxh | 1 + Renderer.cs | 18 ++- 6 files changed, 126 insertions(+), 44 deletions(-) diff --git a/Effects/DeferredPBR_DirectionalLightEffect.cs b/Effects/DeferredPBR_DirectionalLightEffect.cs index fb24e78..5e1f919 100644 --- a/Effects/DeferredPBR_DirectionalLightEffect.cs +++ b/Effects/DeferredPBR_DirectionalLightEffect.cs @@ -22,6 +22,8 @@ namespace Kav EffectParameter cascadeFarPlanesParam; + EffectParameter shadowMapSizeParam; + EffectParameter lightSpaceMatrixOneParam; EffectParameter lightSpaceMatrixTwoParam; EffectParameter lightSpaceMatrixThreeParam; @@ -46,6 +48,8 @@ namespace Kav public readonly float[] CascadeFarPlanes; + public int ShadowMapSize { get; set; } + public Matrix LightSpaceMatrixOne { get; set; } public Matrix LightSpaceMatrixTwo { get; set; } public Matrix LightSpaceMatrixThree { get; set; } @@ -82,6 +86,8 @@ namespace Kav CascadeFarPlanes[i] = cloneSource.CascadeFarPlanes[i]; } + ShadowMapSize = cloneSource.ShadowMapSize; + LightSpaceMatrixOne = cloneSource.LightSpaceMatrixOne; LightSpaceMatrixTwo = cloneSource.LightSpaceMatrixTwo; LightSpaceMatrixThree = cloneSource.LightSpaceMatrixThree; @@ -113,6 +119,7 @@ namespace Kav directionalLightColorParam.SetValue(DirectionalLightColor); cascadeFarPlanesParam.SetValue(CascadeFarPlanes); + shadowMapSizeParam.SetValue(ShadowMapSize); lightSpaceMatrixOneParam.SetValue(LightSpaceMatrixOne); lightSpaceMatrixTwoParam.SetValue(LightSpaceMatrixTwo); @@ -141,6 +148,8 @@ namespace Kav cascadeFarPlanesParam = Parameters["CascadeFarPlanes"]; + shadowMapSizeParam = Parameters["ShadowMapSize"]; + lightSpaceMatrixOneParam = Parameters["LightSpaceMatrixOne"]; lightSpaceMatrixTwoParam = Parameters["LightSpaceMatrixTwo"]; lightSpaceMatrixThreeParam = Parameters["LightSpaceMatrixThree"]; diff --git a/Effects/FXB/DeferredPBR_DirectionalLightEffect.fxb b/Effects/FXB/DeferredPBR_DirectionalLightEffect.fxb index e47ec4036bb500428a8c76598e5740752765984b..adbc9a72a67b265ca1cb5176c01e4f14c0fae6d8 100644 GIT binary patch literal 11216 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 OLKDro+x+(@=zjr((opOG diff --git a/Effects/HLSL/DeferredPBR_DirectionalLightEffect.fx b/Effects/HLSL/DeferredPBR_DirectionalLightEffect.fx index 77a3860..06f3a6b 100644 --- a/Effects/HLSL/DeferredPBR_DirectionalLightEffect.fx +++ b/Effects/HLSL/DeferredPBR_DirectionalLightEffect.fx @@ -21,18 +21,40 @@ BEGIN_CONSTANTS float CascadeFarPlanes[NUM_SHADOW_CASCADES] _ps(c3) _cb(c3); + float ShadowMapSize _ps(c7) _cb(c7); + MATRIX_CONSTANTS - float4x4 LightSpaceMatrixOne _ps(c7) _cb(c7); - float4x4 LightSpaceMatrixTwo _ps(c11) _cb(c11); - float4x4 LightSpaceMatrixThree _ps(c15) _cb(c15); - float4x4 LightSpaceMatrixFour _ps(c19) _cb(c19); + float4x4 LightSpaceMatrixOne _ps(c8) _cb(c8); + float4x4 LightSpaceMatrixTwo _ps(c12) _cb(c12); + float4x4 LightSpaceMatrixThree _ps(c16) _cb(c16); + float4x4 LightSpaceMatrixFour _ps(c20) _cb(c20); // used to select shadow cascade - float4x4 ViewMatrix _ps(c23) _cb(c23); + float4x4 ViewMatrix _ps(c24) _cb(c24); END_CONSTANTS +static float2 poissonDisk[16] = +{ + float2( -0.94201624, -0.39906216 ), + float2( 0.94558609, -0.76890725 ), + float2( -0.094184101, -0.92938870 ), + float2( 0.34495938, 0.29387760 ), + float2( -0.91588581, 0.45771432 ), + float2( -0.81544232, -0.87912464 ), + float2( -0.38277543, 0.27676845 ), + float2( 0.97484398, 0.75648379 ), + float2( 0.44323325, -0.97511554 ), + float2( 0.53742981, -0.47373420 ), + float2( -0.26496911, -0.41893023 ), + float2( 0.79197514, 0.19090188 ), + float2( -0.24188840, 0.99706507 ), + float2( -0.81409955, 0.91437590 ), + float2( 0.19984126, 0.78641367 ), + float2( 0.14383161, -0.14100790 ) +}; + struct VertexInput { float4 Position : POSITION; @@ -57,6 +79,30 @@ PixelInput main_vs(VertexInput input) // Pixel Shader +// Returns a random number based on a vec3 and an int. +float random(float3 seed, int i){ + float4 seed4 = float4(seed, i); + float dot_product = dot(seed4, float4(12.9898,78.233,45.164,94.673)); + return frac(sin(dot_product) * 43758.5453); +} + +float PoissonCoord(sampler shadowMap, float3 worldPosition, float2 texCoord, float fragmentDepth, float bias) +{ + float visibility = 1.0; + + for (int i = 0; i < 16; i++) + { + int index = int(16.0 * random(floor(worldPosition * 1000.0), i)) % 16; + + if (tex2D(shadowMap, texCoord + poissonDisk[i] / 700.0).r < fragmentDepth - bias) + { + visibility -= 0.2; + } + } + + return visibility; +} + float ComputeShadow(float3 positionWorldSpace, float3 N, float3 L) { float bias = 0.005 * tan(acos(dot(N, L))); @@ -104,42 +150,58 @@ float ComputeShadow(float3 positionWorldSpace, float3 N, float3 L) projectionCoords.y *= -1; // in XNA clip z is 0 to 1 already - float inc = 1.0 / 1024.0; - - float shadowFactor = 0; - for (int row = -1; row <= 1; row++) - { - for (int col = -1; col <= 1; col++) - { - float closestDepth; - if (shadowCascadeIndex == 0) - { - closestDepth = SAMPLE_TEXTURE(shadowMapOne, projectionCoords.xy + float2(row, col) * inc).r; - } - else if (shadowCascadeIndex == 1) - { - closestDepth = SAMPLE_TEXTURE(shadowMapTwo, projectionCoords.xy + float2(row, col) * inc).r; - } - else if (shadowCascadeIndex == 2) - { - closestDepth = SAMPLE_TEXTURE(shadowMapThree, projectionCoords.xy + float2(row, col) * inc).r; - } - else - { - closestDepth = SAMPLE_TEXTURE(shadowMapFour, projectionCoords.xy + float2(row, col) * inc).r; - } - shadowFactor += projectionCoords.z - bias > closestDepth ? 1.0 : 0.0; - } - } - - shadowFactor /= 9.0; - if (projectionCoords.z > 1.0) { - shadowFactor = 1.0; + return 1.0; } - return shadowFactor; + float inc = 1.0 / ShadowMapSize; // TODO: shadow map size uniform + + // PCF + Poisson soft shadows + float visibility = 0.0; + // for (int row = -1; row <= 1; row++) + // { + // for (int col = -1; col <= 1; col++) + // { + // if (shadowCascadeIndex == 0) + // { + // visibility += PoissonCoord(SAMPLER(shadowMapOne), positionWorldSpace, projectionCoords.xy + float2(row, col) * inc, projectionCoords.z, bias); + // } + // else if (shadowCascadeIndex == 1) + // { + // visibility += PoissonCoord(SAMPLER(shadowMapTwo), positionWorldSpace, projectionCoords.xy + float2(row, col) * inc, projectionCoords.z, bias); + // } + // else if (shadowCascadeIndex == 2) + // { + // visibility += PoissonCoord(SAMPLER(shadowMapThree), positionWorldSpace, projectionCoords.xy + float2(row, col) * inc, projectionCoords.z, bias); + // } + // else + // { + // visibility += PoissonCoord(SAMPLER(shadowMapFour), positionWorldSpace, projectionCoords.xy + float2(row, col) * inc, projectionCoords.z, bias); + // } + // } + // } + + // visibility /= 9.0; + + if (shadowCascadeIndex == 0) + { + visibility = PoissonCoord(SAMPLER(shadowMapOne), positionWorldSpace, projectionCoords.xy, projectionCoords.z, bias); + } + else if (shadowCascadeIndex == 1) + { + visibility = PoissonCoord(SAMPLER(shadowMapTwo), positionWorldSpace, projectionCoords.xy, projectionCoords.z, bias); + } + else if (shadowCascadeIndex == 2) + { + visibility = PoissonCoord(SAMPLER(shadowMapThree), positionWorldSpace, projectionCoords.xy, projectionCoords.z, bias); + } + else + { + visibility = PoissonCoord(SAMPLER(shadowMapFour), positionWorldSpace, projectionCoords.xy, projectionCoords.z, bias); + } + + return visibility; } float4 ComputeColor( @@ -159,7 +221,7 @@ float4 ComputeColor( float3 radiance = DirectionalLightColor; float shadow = ComputeShadow(worldPosition, N, L); - float3 color = ComputeLight(L, radiance, F0, V, N, albedo, metallic, roughness, (1.0 - shadow)); + float3 color = ComputeLight(L, radiance, F0, V, N, albedo, metallic, roughness, shadow); return float4(color, 1.0); } diff --git a/Effects/HLSL/Lighting.fxh b/Effects/HLSL/Lighting.fxh index 1cc6ae8..e57b391 100644 --- a/Effects/HLSL/Lighting.fxh +++ b/Effects/HLSL/Lighting.fxh @@ -49,7 +49,7 @@ float3 ComputeLight( float3 albedo, float metallic, float roughness, - float shadow + float visibility ) { float3 H = normalize(V + L); @@ -67,5 +67,5 @@ float3 ComputeLight( kD *= 1.0 - metallic; float NdotL = max(dot(N, L), 0.0); - return (kD * albedo / PI + specular) * radiance * NdotL * shadow; + return (kD * albedo / PI + specular) * radiance * NdotL * visibility; } diff --git a/Effects/HLSL/Macros.fxh b/Effects/HLSL/Macros.fxh index 91d1702..c0aaaac 100644 --- a/Effects/HLSL/Macros.fxh +++ b/Effects/HLSL/Macros.fxh @@ -54,4 +54,5 @@ #define SAMPLE_TEXTURE(Name, texCoord) tex2D(Name##Sampler, texCoord) #define SAMPLE_CUBEMAP(Name, texCoord) texCUBE(Name##Sampler, texCoord) #define SAMPLE_CUBEMAP_LOD(Name, texCoord) texCUBElod(Name##Sampler, texCoord) +#define SAMPLER(Name) Name##Sampler #endif diff --git a/Renderer.cs b/Renderer.cs index 82a9a0f..37eead5 100644 --- a/Renderer.cs +++ b/Renderer.cs @@ -7,6 +7,7 @@ namespace Kav public class Renderer { private const int MAX_SHADOW_CASCADES = 4; + private int ShadowMapSize { get; } private GraphicsDevice GraphicsDevice { get; } private int RenderDimensionsX { get; } @@ -34,12 +35,19 @@ namespace Kav private SpriteBatch SpriteBatch { get; } - public Renderer(GraphicsDevice graphicsDevice, int renderDimensionsX, int renderDimensionsY, int numShadowCascades) - { + public Renderer( + GraphicsDevice graphicsDevice, + int renderDimensionsX, + int renderDimensionsY, + int numShadowCascades, + int shadowMapSize + ) { GraphicsDevice = graphicsDevice; RenderDimensionsX = renderDimensionsX; RenderDimensionsY = renderDimensionsY; + ShadowMapSize = shadowMapSize; + NumShadowCascades = (int)MathHelper.Clamp(numShadowCascades, 1, MAX_SHADOW_CASCADES); ShadowRenderTargets = new RenderTarget2D[numShadowCascades]; @@ -47,8 +55,8 @@ namespace Kav { ShadowRenderTargets[i] = new RenderTarget2D( GraphicsDevice, - 1024, - 1024, + ShadowMapSize, + ShadowMapSize, false, SurfaceFormat.Single, DepthFormat.Depth24 @@ -126,6 +134,8 @@ namespace Kav DeferredPointLightEffect = new DeferredPBR_PointLightEffect(GraphicsDevice); DeferredDirectionalLightEffect = new DeferredPBR_DirectionalLightEffect(GraphicsDevice); + DeferredDirectionalLightEffect.ShadowMapSize = ShadowMapSize; + FullscreenTriangle = new VertexBuffer(GraphicsDevice, typeof(VertexPositionTexture), 3, BufferUsage.WriteOnly); FullscreenTriangle.SetData(new VertexPositionTexture[3] { new VertexPositionTexture(new Vector3(-1, -3, 0), new Vector2(0, 2)),