From 08a4dbdfdf3e35f2ebdc592c0ee4dc3f3e4895fe Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Sat, 10 May 2025 22:52:46 +0200 Subject: [PATCH] SHADOWS WORK --- res/shaders/BasePass.slang | 32 ++++++++++-------- res/shaders/ToneMapping.slang | 2 +- src/Engine/Component/Camera.h | 4 +-- src/Engine/Graphics/RenderPass/ShadowPass.cpp | 16 ++++----- src/Engine/Graphics/Window.cpp | 33 ++++++++++++++++--- src/Engine/Scene/LightEnvironment.cpp | 8 ++--- 6 files changed, 63 insertions(+), 32 deletions(-) diff --git a/res/shaders/BasePass.slang b/res/shaders/BasePass.slang index 7942804..c4dfc27 100644 --- a/res/shaders/BasePass.slang +++ b/res/shaders/BasePass.slang @@ -11,6 +11,12 @@ struct LightCullingData }; ParameterBlock pLightCullingData; +static const float4x4 biasMat = float4x4( + 0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0); + [shader("pixel")] float4 fragmentMain(in FragmentParameter params) : SV_Target { @@ -24,22 +30,22 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target float3 result = float3(0, 0, 0); for(int i = 0; i < pLightEnv.numDirectionalLights; ++i) { - float4 lightSpacePos = mul(pLightEnv.directionalLights[i].lightSpaceMatrix, float4(params.position_WS, 1)); - float3 projCoords = lightSpacePos.xyz / lightSpacePos.w; - projCoords.xy = projCoords.xy * 0.5 + 0.5; - projCoords.z /= 2; - float closestDepth = pLightEnv.shadowMap.Sample(pLightEnv.shadowSampler, projCoords.xy).r; - float currentDepth = projCoords.z; - float bias = max(0.05 * (1.0 - dot(brdf.getNormal(), pLightEnv.directionalLights[i].direction.xyz)), 0.005); - float shadow = currentDepth + bias < closestDepth ? 1.0 : 0.0; + float4 lightSpacePos = mul(biasMat, mul(pLightEnv.directionalLights[i].lightSpaceMatrix, float4(params.position_WS, 1))); + float4 shadowCoord = lightSpacePos / lightSpacePos.w; + float shadow = 1.0f; + float dist = pLightEnv.shadowMap.Sample(pLightEnv.shadowSampler, shadowCoord.xy).r; + if (shadowCoord.w > 0 && dist > shadowCoord.z) + { + shadow = 0; + } - result += float3(currentDepth, 0, 0);//shadow * pLightEnv.directionalLights[i].illuminate(lightingParams, brdf); + result += shadow * pLightEnv.directionalLights[i].illuminate(lightingParams, brdf); } - for (uint i = 0; i < lightCount; ++i) + for (uint i = 0; i < pLightEnv.numPointLights; ++i) { - uint lightIndex = pLightCullingData.lightIndexList[startOffset + i]; - result += pLightEnv.pointLights[lightIndex].illuminate(lightingParams, brdf); + //uint lightIndex = pLightCullingData.lightIndexList[startOffset + i]; + result += pLightEnv.pointLights[i].illuminate(lightingParams, brdf); } - result += brdf.evaluateAmbient(lightingParams.viewDir_WS); + //result += brdf.evaluateAmbient(lightingParams.viewDir_WS); return float4(result, brdf.getAlpha()); } \ No newline at end of file diff --git a/res/shaders/ToneMapping.slang b/res/shaders/ToneMapping.slang index b4dd02a..ecd0fd3 100644 --- a/res/shaders/ToneMapping.slang +++ b/res/shaders/ToneMapping.slang @@ -113,5 +113,5 @@ float4 toneMapping(float2 uv : UV) : SV_Target value = agxLook(value); value = agxEotf(value); - return float4(value, 1); + return float4(hdrValue, 1); } diff --git a/src/Engine/Component/Camera.h b/src/Engine/Component/Camera.h index b2ca8f9..8957220 100644 --- a/src/Engine/Component/Camera.h +++ b/src/Engine/Component/Camera.h @@ -6,8 +6,8 @@ namespace Seele { namespace Component { struct Camera { - float nearPlane = 0.001f; - float farPlane = 10000.0f; + float nearPlane = 0.1f; + float farPlane = 1000.0f; bool mainCamera = false; }; } // namespace Component diff --git a/src/Engine/Graphics/RenderPass/ShadowPass.cpp b/src/Engine/Graphics/RenderPass/ShadowPass.cpp index 47edacd..b4b2c82 100644 --- a/src/Engine/Graphics/RenderPass/ShadowPass.cpp +++ b/src/Engine/Graphics/RenderPass/ShadowPass.cpp @@ -94,6 +94,8 @@ void ShadowPass::render() { command->setViewport(shadowViewport); const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); + constexpr float depthBiasConstant = -1.25f; + constexpr float depthBiasSlope = -1.75f; if (graphics->supportMeshShading()) { Gfx::MeshPipelineCreateInfo pipelineInfo = { .taskShader = collection->taskShader, @@ -104,10 +106,9 @@ void ShadowPass::render() { .rasterizationState = { .cullMode = Gfx::SE_CULL_MODE_NONE, - }, - .colorBlend = - { - .attachmentCount = 1, + .depthBiasEnable = true, + .depthBiasConstantFactor = depthBiasConstant, + .depthBiasSlopeFactor = depthBiasSlope, }, }; Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); @@ -121,10 +122,9 @@ void ShadowPass::render() { .rasterizationState = { .cullMode = Gfx::SE_CULL_MODE_NONE, - }, - .colorBlend = - { - .attachmentCount = 1, + .depthBiasEnable = true, + .depthBiasConstantFactor = depthBiasConstant, + .depthBiasSlopeFactor = depthBiasSlope, }, }; Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); diff --git a/src/Engine/Graphics/Window.cpp b/src/Engine/Graphics/Window.cpp index 7c8afec..ca40205 100644 --- a/src/Engine/Graphics/Window.cpp +++ b/src/Engine/Graphics/Window.cpp @@ -10,8 +10,7 @@ Window::~Window() {} Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo) : sizeX(viewportInfo.dimensions.size.x), sizeY(viewportInfo.dimensions.size.y), offsetX(viewportInfo.dimensions.offset.x), offsetY(viewportInfo.dimensions.offset.y), fieldOfView(viewportInfo.fieldOfView), orthoLeft(viewportInfo.left), - orthoRight(viewportInfo.right), orthoTop(viewportInfo.top), orthoBottom(viewportInfo.bottom), - owner(owner) { + orthoRight(viewportInfo.right), orthoTop(viewportInfo.top), orthoBottom(viewportInfo.bottom), owner(owner) { if (owner != nullptr) { sizeX = std::min(owner->getFramebufferWidth(), sizeX); sizeY = std::min(owner->getFramebufferHeight(), sizeY); @@ -23,8 +22,34 @@ Viewport::~Viewport() {} Matrix4 Viewport::getProjectionMatrix(float nearPlane, float farPlane) const { Matrix4 correctionMatrix = Matrix4(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1 / 2.f, 0, 0, 0, 1 / 2.f, 1); if (fieldOfView > 0.0f) { - Matrix4 projectionMatrix = glm::perspective(fieldOfView, sizeX / static_cast(sizeY), nearPlane, farPlane); - return correctionMatrix * projectionMatrix; + const float aspect = static_cast(sizeX) / sizeY; + const float e = 1.0f / std::tan(fieldOfView * 0.5f); + return { + { + e / aspect, + 0.0f, + 0.0f, + 0.0f, + }, + { + 0.0f, + -e, + 0.0f, + 0.0f, + }, + { + 0.0f, + 0.0f, + 0.5f * (farPlane + nearPlane) / (nearPlane - farPlane), + -1.0f, + }, + { + 0.0f, + 0.0f, + (farPlane * nearPlane) / (nearPlane - farPlane), + 0.0f, + }, + }; } else { return correctionMatrix * glm::ortho(orthoLeft, orthoRight, orthoBottom, orthoTop, nearPlane, farPlane); } diff --git a/src/Engine/Scene/LightEnvironment.cpp b/src/Engine/Scene/LightEnvironment.cpp index 1a03c2a..0691e9b 100644 --- a/src/Engine/Scene/LightEnvironment.cpp +++ b/src/Engine/Scene/LightEnvironment.cpp @@ -75,7 +75,7 @@ void LightEnvironment::addDirectionalLight(const Component::DirectionalLight& di dirs.add(ShaderDirectionalLight{ .color = Vector4(dirLight.color, dirLight.intensity), .direction = Vector4(transform.getForward(), 0), - .lightSpaceMatrix = correctionMatrix * glm::ortho(-100.0f, 100.0f, -100.0f, 100.0f, -100.0f, 100.0f) * cameraMatrix, + .lightSpaceMatrix = correctionMatrix * glm::ortho(-100.0f, 100.0f, -100.0f, 100.0f, 100.0f, -100.0f) * cameraMatrix, }); directionalTransforms.add(transform); if (shadowMaps.size() < dirs.size()) { @@ -90,9 +90,9 @@ void LightEnvironment::addDirectionalLight(const Component::DirectionalLight& di shadowMaps.back()->changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, Gfx::SE_ACCESS_NONE, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT); shadowSamplers.add(graphics->createSampler(SamplerCreateInfo{ - .addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, - .addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, - .addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + .addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, .name = "ShadowSampler", })); }