From a76dfafbaa91ec93a852853f6c77c463203a9311 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 17 Sep 2023 14:59:24 +0200 Subject: [PATCH] Fix misc bugs in the fogball implementation - it works now --- .../rendering/vulkan/buffers/vk_rsbuffers.h | 2 +- .../descriptorsets/vk_descriptorset.cpp | 2 +- .../rendering/vulkan/shaders/vk_shader.h | 5 ++++ .../rendering/vulkan/vk_renderstate.cpp | 2 +- .../hwrenderer/scene/hw_drawinfo.cpp | 27 ++++++++++++++----- src/rendering/hwrenderer/scene/hw_drawinfo.h | 1 - src/rendering/hwrenderer/scene/hw_sprites.cpp | 2 +- wadsrc/static/shaders/scene/fogball.glsl | 3 ++- 8 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/common/rendering/vulkan/buffers/vk_rsbuffers.h b/src/common/rendering/vulkan/buffers/vk_rsbuffers.h index a25f8bb2e..4ab5979e1 100644 --- a/src/common/rendering/vulkan/buffers/vk_rsbuffers.h +++ b/src/common/rendering/vulkan/buffers/vk_rsbuffers.h @@ -54,7 +54,7 @@ public: struct { int UploadIndex = 0; - int Count = 1000; + int Count = 10000; std::unique_ptr UBO; void* Data = nullptr; } Fogballbuffer; diff --git a/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp b/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp index afb8e0345..1c974e72d 100644 --- a/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp +++ b/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp @@ -65,7 +65,7 @@ void VkDescriptorSetManager::Init() .AddBuffer(rsbufferset.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->MatrixBuffer->UBO(), 0, sizeof(MatricesUBO)) .AddBuffer(rsbufferset.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->StreamBuffer->UBO(), 0, sizeof(StreamUBO)) .AddBuffer(rsbufferset.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Lightbuffer.UBO.get(), 0, sizeof(LightBufferUBO)) - .AddBuffer(rsbufferset.get(), 4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Fogballbuffer.UBO.get(), 0, sizeof(Fogball)) + .AddBuffer(rsbufferset.get(), 4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Fogballbuffer.UBO.get(), 0, sizeof(FogballBufferUBO)) .AddBuffer(rsbufferset.get(), 5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, rsbuffers->Bonebuffer.SSO.get()) .Execute(fb->GetDevice()); diff --git a/src/common/rendering/vulkan/shaders/vk_shader.h b/src/common/rendering/vulkan/shaders/vk_shader.h index f5e9ff1d7..4bf446ec2 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.h +++ b/src/common/rendering/vulkan/shaders/vk_shader.h @@ -42,6 +42,11 @@ struct LightBufferUBO #define MAX_FOGBALL_DATA ((int)(65536 / sizeof(Fogball))) +struct FogballBufferUBO +{ + Fogball fogballs[MAX_FOGBALL_DATA]; +}; + struct PushConstants { int uDataIndex; // streamdata index diff --git a/src/common/rendering/vulkan/vk_renderstate.cpp b/src/common/rendering/vulkan/vk_renderstate.cpp index 4687aecd7..c43a6f97a 100644 --- a/src/common/rendering/vulkan/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/vk_renderstate.cpp @@ -502,7 +502,7 @@ void VkRenderState::ApplyBufferSets() uint32_t matrixOffset = mRSBuffers->MatrixBuffer->Offset(); uint32_t streamDataOffset = mRSBuffers->StreamBuffer->Offset(); uint32_t lightsOffset = mLightIndex >= 0 ? (uint32_t)(mLightIndex / MAX_LIGHT_DATA) * sizeof(LightBufferUBO) : mLastLightsOffset; - uint32_t fogballsOffset = mFogballIndex >= 0 ? (uint32_t)(mFogballIndex / MAX_FOGBALL_DATA) * sizeof(Fogball) : mLastFogballsOffset; + uint32_t fogballsOffset = mFogballIndex >= 0 ? (uint32_t)(mFogballIndex / MAX_FOGBALL_DATA) * sizeof(FogballBufferUBO) : mLastFogballsOffset; if (mViewpointOffset != mLastViewpointOffset || matrixOffset != mLastMatricesOffset || streamDataOffset != mLastStreamDataOffset || lightsOffset != mLastLightsOffset || fogballsOffset != mLastFogballsOffset) { auto descriptors = fb->GetDescriptorSetManager(); diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp index f63411635..dee9d418f 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp @@ -411,6 +411,16 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state) PrepareUnhandledMissingTextures(state); DispatchRenderHacks(state); + // Sort fogballs by view order + FVector3 campos(vp.Pos); + std::sort(Fogballs.begin(), Fogballs.end(), [&](const Fogball& a, const Fogball& b) -> bool { + FVector3 rayA = a.Position - campos; + FVector3 rayB = b.Position - campos; + float distSqrA = rayA | rayA; + float distSqrB = rayB | rayB; + return distSqrA > distSqrB; + }); + ProcessAll.Unclock(); } @@ -811,14 +821,16 @@ void HWDrawInfo::DrawScene(int drawmode, FRenderState& state) CreateScene(false, state); } + if (!outer) // Fogballs have no portal support. Always use the outermost scene's fogballs for now + { + int fogballIndex = state.UploadFogballs(Fogballs); + state.SetFogballIndex(fogballIndex); + } + state.SetDepthMask(true); if (!gl_no_skyclear) drawctx->portalState.RenderFirstSkyPortal(recursion, this, state); - int fogballIndex = state.UploadFogballs(Fogballs); - - state.SetFogballIndex(fogballIndex); RenderScene(state); - state.SetFogballIndex(-1); if (applySSAO && state.GetPassType() == GBUFFER_PASS) { @@ -832,9 +844,12 @@ void HWDrawInfo::DrawScene(int drawmode, FRenderState& state) drawctx->portalState.EndFrame(this, state); recursion--; - state.SetFogballIndex(fogballIndex); RenderTranslucent(state); - state.SetFogballIndex(-1); + + if (!outer) + { + state.SetFogballIndex(-1); + } } diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.h b/src/rendering/hwrenderer/scene/hw_drawinfo.h index bd81bf9a2..a2d32d4dc 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.h +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.h @@ -34,7 +34,6 @@ struct particle_t; struct FDynLightData; struct HUDSprite; class ACorona; -class AFogball; class Clipper; class HWPortal; class HWScenePortalBase; diff --git a/src/rendering/hwrenderer/scene/hw_sprites.cpp b/src/rendering/hwrenderer/scene/hw_sprites.cpp index 1309043e9..b3a816d9f 100644 --- a/src/rendering/hwrenderer/scene/hw_sprites.cpp +++ b/src/rendering/hwrenderer/scene/hw_sprites.cpp @@ -762,7 +762,7 @@ void HWSprite::Process(HWDrawInfo *di, FRenderState& state, AActor* thing, secto Fogball fogball; fogball.Position = FVector3(thing->Pos()); fogball.Radius = (float)thing->renderradius; - fogball.Color = FVector3((float)thing->args[0], (float)thing->args[1], (float)thing->args[2]); + fogball.Color = FVector3(thing->args[0] * (1.0f / 255.0f), thing->args[1] * (1.0f / 255.0f), thing->args[2] * (1.0f / 255.0f)); fogball.Fog = (float)thing->Alpha; di->Fogballs.Push(fogball); return; diff --git a/wadsrc/static/shaders/scene/fogball.glsl b/wadsrc/static/shaders/scene/fogball.glsl index 7031adf43..17d8a35e4 100644 --- a/wadsrc/static/shaders/scene/fogball.glsl +++ b/wadsrc/static/shaders/scene/fogball.glsl @@ -55,7 +55,8 @@ vec4 ProcessFogBalls(vec4 light) vec3 fogcolor = fogballs[i].color * fogballs[i].fog; float density = FogSphereDensity(rayOrigin, rayDirection, sphereCenter, sphereRadius, dbuffer); - light.rgb = mix(light.rgb, fogcolor * density, density); + float alpha = clamp(density, 0.0, 1.0); + light.rgb = mix(light.rgb, fogcolor * density, alpha); } return light;