Fix misc bugs in the fogball implementation - it works now

This commit is contained in:
Magnus Norddahl 2023-09-17 14:59:24 +02:00
commit a76dfafbaa
8 changed files with 32 additions and 12 deletions

View file

@ -54,7 +54,7 @@ public:
struct
{
int UploadIndex = 0;
int Count = 1000;
int Count = 10000;
std::unique_ptr<VulkanBuffer> UBO;
void* Data = nullptr;
} Fogballbuffer;

View file

@ -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());

View file

@ -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

View file

@ -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();

View file

@ -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);
}
}

View file

@ -34,7 +34,6 @@ struct particle_t;
struct FDynLightData;
struct HUDSprite;
class ACorona;
class AFogball;
class Clipper;
class HWPortal;
class HWScenePortalBase;

View file

@ -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;

View file

@ -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;