From a3f5ad2841cb757d08e5cc583ed4ec55214011c2 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Fri, 23 Feb 2024 08:31:21 +0100 Subject: [PATCH] fixing light culling --- CMakeLists.txt | 2 +- res/shaders/ComputeFrustums.slang | 10 +++++----- res/shaders/LightCulling.slang | 14 +++++++------- res/shaders/lib/Common.slang | 16 ++++++++++++++-- res/shaders/lib/LightEnv.slang | 16 ++++++++-------- src/Engine/Graphics/RenderPass/BasePass.cpp | 1 - src/Engine/Graphics/RenderPass/RenderPass.cpp | 1 + src/Engine/Graphics/RenderPass/RenderPass.h | 1 + 8 files changed, 37 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8694e93..eb079a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,7 +94,7 @@ target_link_libraries(AssetViewer PRIVATE Engine) target_include_directories(AssetViewer PRIVATE src/AssetViewer) if(MSVC) - set(_CRT_SECURE_NO_WARNINGS) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) target_compile_options(Engine PUBLIC /std:c++20 /Zi /MP14 /W4 /DEBUG /wd4505) target_compile_options(Editor PUBLIC /std:c++20 /Zi /MP14 /W4 /DEBUG) target_sources(Engine INTERFACE diff --git a/res/shaders/ComputeFrustums.slang b/res/shaders/ComputeFrustums.slang index 2832cab..a1d5bbc 100644 --- a/res/shaders/ComputeFrustums.slang +++ b/res/shaders/ComputeFrustums.slang @@ -15,13 +15,13 @@ void computeFrustums(ComputeShaderInput in) { float3 origin = float3(0, 0, 0); float3 corners[4] = { - screenToClip(float3(float2(in.dispatchThreadID.x + 0, in.dispatchThreadID.y + 0) * BLOCK_SIZE, -1.0f)), - screenToClip(float3(float2(in.dispatchThreadID.x + 1, in.dispatchThreadID.y + 0) * BLOCK_SIZE, -1.0f)), - screenToClip(float3(float2(in.dispatchThreadID.x + 0, in.dispatchThreadID.y + 1) * BLOCK_SIZE, -1.0f)), - screenToClip(float3(float2(in.dispatchThreadID.x + 1, in.dispatchThreadID.y + 1) * BLOCK_SIZE, -1.0f)) + screenToView(float4(float2(in.dispatchThreadID.x + 0, in.dispatchThreadID.y + 0) * BLOCK_SIZE, -1.0f, 1.0f)).xyz, + screenToView(float4(float2(in.dispatchThreadID.x + 1, in.dispatchThreadID.y + 0) * BLOCK_SIZE, -1.0f, 1.0f)).xyz, + screenToView(float4(float2(in.dispatchThreadID.x + 0, in.dispatchThreadID.y + 1) * BLOCK_SIZE, -1.0f, 1.0f)).xyz, + screenToView(float4(float2(in.dispatchThreadID.x + 1, in.dispatchThreadID.y + 1) * BLOCK_SIZE, -1.0f, 1.0f)).xyz }; Frustum frustum; - frustum.sides[0] = computePlane(origin, corners[2], corners[1]); + frustum.sides[0] = computePlane(origin, corners[2], corners[0]); frustum.sides[1] = computePlane(origin, corners[1], corners[3]); frustum.sides[2] = computePlane(origin, corners[0], corners[1]); frustum.sides[3] = computePlane(origin, corners[3], corners[2]); diff --git a/res/shaders/LightCulling.slang b/res/shaders/LightCulling.slang index 825fcc9..0de119e 100644 --- a/res/shaders/LightCulling.slang +++ b/res/shaders/LightCulling.slang @@ -89,20 +89,20 @@ void cullLights(ComputeShaderInput in) float fMinDepth = asfloat(uMinDepth); float fMaxDepth = asfloat(uMaxDepth); - float minDepth = fMinDepth; - float maxDepth = fMaxDepth; - float nearClip = 0.1f; + float minDepthVS = clipToView(float4(0, 0, fMinDepth, 1)).z; + float maxDepthVS = clipToView(float4(0, 0, fMaxDepth, 1)).z; + float nearClipVS = clipToView(float4(0, 0, 0, 1)).z; - Plane minPlane = {float3(0, 0, -1), -minDepth}; + Plane minPlane = {float3(0, 0, -1), -minDepthVS}; for ( uint i = in.groupIndex; i < pLightEnv.numPointLights; i += BLOCK_SIZE * BLOCK_SIZE ) { PointLight light = pLightEnv.pointLights[i]; - float3 lightClip = light.getClipPosition(); - if(light.insideFrustum(groupFrustum, lightClip, nearClip, maxDepth)) + float3 light_VS = light.getViewPosition(); + if(light.insideFrustum(groupFrustum, light_VS, nearClipVS, maxDepthVS)) { tAppendLight(i); - if(!light.insidePlane(minPlane, lightClip)) + if(!light.insidePlane(minPlane, light_VS)) { oAppendLight(i); } diff --git a/res/shaders/lib/Common.slang b/res/shaders/lib/Common.slang index c03e43e..de10e1d 100644 --- a/res/shaders/lib/Common.slang +++ b/res/shaders/lib/Common.slang @@ -6,18 +6,30 @@ struct ViewParameter { float4x4 viewMatrix; float4x4 projectionMatrix; + float4x4 inverseProjection; float4 cameraPos_WS; float2 screenDimensions; } layout(set = 0) ParameterBlock pViewParams; -float3 screenToClip(float3 screen) +float4 clipToView(float4 clip) +{ + float4 view = mul(pViewParams.inverseProjection, clip); + + view = view / view.w; + + return view; +} + +float4 screenToView(float4 screen) { float2 texCoord = screen.xy / pViewParams.screenDimensions; // Convert to clip space - return float3( float2( texCoord.x, 1.0f-texCoord.y ) * 2.0f - 1.0f, screen.z); + float4 clip = float4( float2( texCoord.x, 1.0f-texCoord.y ) * 2.0f - 1.0f, screen.z, screen.w); + + return clipToView(clip); } struct Plane diff --git a/res/shaders/lib/LightEnv.slang b/res/shaders/lib/LightEnv.slang index c5891e4..074ef11 100644 --- a/res/shaders/lib/LightEnv.slang +++ b/res/shaders/lib/LightEnv.slang @@ -32,27 +32,27 @@ struct PointLight : ILightEnv float illuminance = max(1 - d / colorRange.w, 0); return illuminance * brdf.evaluate(params.tbn, params.viewDir_TS, -normalize(lightDir_TS), colorRange.xyz); } - float3 getClipPosition() + float3 getViewPosition() { - float4 position_CS = mul(pViewParams.projectionMatrix, mul(pViewParams.viewMatrix, position_WS)); - return position_CS.xyz / position_CS.w; + float4 position_VS = mul(pViewParams.viewMatrix, position_WS); + return position_VS.xyz / position_VS.w; } - bool insidePlane(Plane plane, float3 position_CS) + bool insidePlane(Plane plane, float3 position_VS) { - return dot(plane.n, position_CS) - plane.d < -colorRange.w; + return dot(plane.n, position_VS) - plane.d < -colorRange.w; } - bool insideFrustum(Frustum frustum, float3 position_CS, float minDepth, float maxDepth) + bool insideFrustum(Frustum frustum, float3 position_VS, float minDepth, float maxDepth) { bool result = true; - if(position_CS.z - colorRange.w > minDepth || position_CS.z + colorRange.w < maxDepth) + if(position_VS.z - colorRange.w > minDepth || position_VS.z + colorRange.w < maxDepth) { result = false; } for(int i = 0; i < 4 && result; ++i) { - if(insidePlane(frustum.sides[i], position_CS)) + if(insidePlane(frustum.sides[i], position_VS)) { result = false; } diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 4a4be17..eef64ad 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -169,7 +169,6 @@ void BasePass::render() } graphics->executeCommands(commands); graphics->endRenderPass(); - vkDeviceWaitIdle(((Vulkan::Graphics*)graphics.getHandle())->getDevice()); } void BasePass::endFrame() diff --git a/src/Engine/Graphics/RenderPass/RenderPass.cpp b/src/Engine/Graphics/RenderPass/RenderPass.cpp index d6c4c12..aae6bd1 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/RenderPass.cpp @@ -28,6 +28,7 @@ void RenderPass::beginFrame(const Component::Camera& cam) viewParams = { .viewMatrix = cam.getViewMatrix(), .projectionMatrix = viewport->getProjectionMatrix(), + .inverseProjection = glm::inverse(viewport->getProjectionMatrix()), .cameraPosition = Vector4(cam.getCameraPosition(), 1), .screenDimensions = Vector2(static_cast(viewport->getWidth()), static_cast(viewport->getHeight())), }; diff --git a/src/Engine/Graphics/RenderPass/RenderPass.h b/src/Engine/Graphics/RenderPass/RenderPass.h index ed3312e..1b7d0ed 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.h +++ b/src/Engine/Graphics/RenderPass/RenderPass.h @@ -31,6 +31,7 @@ protected: { Matrix4 viewMatrix; Matrix4 projectionMatrix; + Matrix4 inverseProjection; Vector4 cameraPosition; Vector2 screenDimensions; } viewParams;