From b43f84def6ccb745f34d90b40901d0be88057d0a Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 16 Sep 2024 01:04:53 +0200 Subject: [PATCH] Hook up light tile visibility test --- .../hwrenderer/data/hw_renderstate.h | 2 +- .../rendering/vulkan/shaders/vk_shader.h | 11 +++---- .../rendering/vulkan/vk_renderstate.cpp | 16 ++++++++-- src/common/rendering/vulkan/vk_renderstate.h | 2 +- .../hwrenderer/scene/hw_drawinfo.cpp | 2 +- .../static/shaders/scene/comp_lighttiles.glsl | 29 +++++++++---------- 6 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/common/rendering/hwrenderer/data/hw_renderstate.h b/src/common/rendering/hwrenderer/data/hw_renderstate.h index 3ad41688d..788947768 100644 --- a/src/common/rendering/hwrenderer/data/hw_renderstate.h +++ b/src/common/rendering/hwrenderer/data/hw_renderstate.h @@ -699,7 +699,7 @@ public: } // Draw level mesh - virtual void DispatchLightTiles() { } + virtual void DispatchLightTiles(const VSMatrix& worldToView, float m5) { } virtual void DrawLevelMesh(LevelMeshDrawType drawType, bool noFragmentShader) { } virtual int GetNextQueryIndex() { return 0; } virtual void BeginQuery() { } diff --git a/src/common/rendering/vulkan/shaders/vk_shader.h b/src/common/rendering/vulkan/shaders/vk_shader.h index 1ad568202..7428f1f46 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.h +++ b/src/common/rendering/vulkan/shaders/vk_shader.h @@ -58,11 +58,12 @@ struct LightTilesPushConstants int additiveCount; int modulatedCount; int subtractiveCount; - int padding; - float rcpF; - float rcpFDivAspect; - float twoRcpViewportSizeX; - float twoRcpViewportSizeY; + int padding0; + FVector2 posToViewA; + FVector2 posToViewB; + FVector2 viewportPos; + FVector2 padding1; + VSMatrix worldToView; }; class VkShaderKey diff --git a/src/common/rendering/vulkan/vk_renderstate.cpp b/src/common/rendering/vulkan/vk_renderstate.cpp index c3ef50672..457cd990a 100644 --- a/src/common/rendering/vulkan/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/vk_renderstate.cpp @@ -940,7 +940,7 @@ void VkRenderState::RunZMinMaxPass() .Execute(cmdbuffer); } -void VkRenderState::DispatchLightTiles() +void VkRenderState::DispatchLightTiles(const VSMatrix& worldToView, float m5) { EndRenderPass(); RunZMinMaxPass(); @@ -951,12 +951,24 @@ void VkRenderState::DispatchLightTiles() .AddBuffer(fb->GetBuffers()->SceneLightTiles.get(), VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_SHADER_WRITE_BIT) .Execute(cmdbuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); + float sceneWidth = (float)fb->GetBuffers()->GetSceneWidth(); + float sceneHeight = (float)fb->GetBuffers()->GetSceneHeight(); + float aspect = sceneWidth / sceneHeight; + + //float tanHalfFovy = tan(fovy * (M_PI / 360.0f)); + float tanHalfFovy = 1.0f / m5; + float invFocalLenX = tanHalfFovy * aspect; + float invFocalLenY = tanHalfFovy; + LightTilesPushConstants pushConstants = {}; //auto mesh = fb->GetLevelMesh()->GetMesh(); //pushConstants.normalLightCount = mesh->Mesh.NormalLightCount; //pushConstants.modulatedLightCount = mesh->Mesh.ModulatedLightCount; //pushConstants.subtractiveLightCount = mesh->Mesh.SubtractiveLightCount; - + pushConstants.posToViewA = { 2.0f * invFocalLenX / sceneWidth, 2.0f * invFocalLenY / sceneHeight }; + pushConstants.posToViewB = { -invFocalLenX, -invFocalLenY }; + pushConstants.viewportPos = { 0.0f, 0.0f }; + pushConstants.worldToView = worldToView; auto pipelines = fb->GetRenderPassManager(); auto descriptors = fb->GetDescriptorSetManager(); cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, pipelines->GetLightTilesPipeline()); diff --git a/src/common/rendering/vulkan/vk_renderstate.h b/src/common/rendering/vulkan/vk_renderstate.h index 80020db86..28a31eabf 100644 --- a/src/common/rendering/vulkan/vk_renderstate.h +++ b/src/common/rendering/vulkan/vk_renderstate.h @@ -57,7 +57,7 @@ public: void ResetVertices() override; // Draw level mesh - void DispatchLightTiles() override; + void DispatchLightTiles(const VSMatrix& worldToView, float m5) override; void DrawLevelMesh(LevelMeshDrawType drawType, bool noFragmentShader) override; int GetNextQueryIndex() override; void BeginQuery() override; diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp index 9d609a5a0..6592e2a20 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp @@ -443,7 +443,7 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state) state.SetColorMask(false); state.SetCulling(Cull_CW); state.DrawLevelMesh(LevelMeshDrawType::Opaque, true); - state.DispatchLightTiles(); + state.DispatchLightTiles(VPUniforms.mViewMatrix, VPUniforms.mProjectionMatrix.get()[5]); state.DrawLevelMesh(LevelMeshDrawType::Masked, false); // To do: properly mark wall top/bottom as opaque so we don't need this if (gl_portals) { diff --git a/wadsrc/static/shaders/scene/comp_lighttiles.glsl b/wadsrc/static/shaders/scene/comp_lighttiles.glsl index a0e6128b3..295907710 100644 --- a/wadsrc/static/shaders/scene/comp_lighttiles.glsl +++ b/wadsrc/static/shaders/scene/comp_lighttiles.glsl @@ -15,15 +15,17 @@ layout(set = 0, binding = 2) buffer Tiles vec4 tiles[]; }; -layout(push_constant) uniform PushConstants +layout(push_constant) uniform LightTilesPushConstants { int additiveCount; int modulatedCount; int subtractiveCount; - int padding; - float rcpF; - float rcpFDivAspect; - vec2 twoRcpViewportSize; + int padding0; + vec2 posToViewA; + vec2 posToViewB; + vec2 viewportPos; + vec2 padding1; + mat4 worldToView; }; struct Tile @@ -57,10 +59,12 @@ void main() int tileModulatedCount = 0; int tileSubtractiveCount = 0; - if (isLightVisible(tile, vec3(-316.0, 64.0, 621.0), 200.0)) + vec4 testLight = vec4(-316.0, 64.0, 621.0, 200.0); + + if (isLightVisible(tile, (worldToView * vec4(testLight.xyz, 1.0)).xyz, testLight.w)) { - vec3 pos = vec3(-316.0, 64.0, 621.0); - float radius = 200.0; + vec3 pos = testLight.xyz; + float radius = testLight.w; vec3 color = vec3(1.0, 1.0, 1.0); float shadowIndex = -1025.0; vec3 spotDir = vec3(0.0); @@ -85,12 +89,9 @@ void main() bool isLightVisible(Tile tile, vec3 lightPos, float lightRadius) { -/* // aabb/sphere test for the light vec3 e = max(tile.aabbMin - lightPos, 0.0f) + max(lightPos - tile.aabbMax, 0.0f); return dot(e, e) <= lightRadius * lightRadius; -*/ - return true; } Tile findTileFrustum(float viewZNear, float viewZFar, uint tileX, uint tileY) @@ -113,9 +114,5 @@ Tile findTileFrustum(float viewZNear, float viewZFar, uint tileX, uint tileY) vec3 unprojectDirection(vec2 pos) { - // float f = 1.0f / tan(fovY * 0.5f); - // float rcpF = 1.0f / f; - // float rcpFDivAspect = 1.0f / (f / aspect); - vec2 normalized = vec2(pos * twoRcpViewportSize) - 1.0; - return vec3(normalized.x * rcpFDivAspect, normalized.y * rcpF, 1.0f); + return vec3(posToViewA * (pos - viewportPos) + posToViewB, 1.0f); }