Quicky hacky solution for blur timings. Not scalable, needs future refactoring

This commit is contained in:
Ethan Adams 2025-02-26 14:33:26 -05:00
parent 46838f2743
commit e2c5462c38
8 changed files with 101 additions and 57 deletions

View file

@ -5,14 +5,16 @@ layout (std140) uniform uPostProcess {
int dt;
vec3 colorMod;
float blurIntensity;
float blurDuration;
float shakeIntensity;
float shakeTime;
float shakeDuration;
int effects;
vec3 colorMod_hud;
float blurIntensity_hud;
float blurDuration_hud;
float shakeIntensity_hud;
float shakeTime_hud;
float shakeDuration_hud;
int effects_hud;
};
out vec4 FragColor;
@ -31,7 +33,9 @@ void main()
{
if (worldOrHud == false)
{
/*
if ((effects & 1) != 0) // BLUR
{
vec4 result = vec4(0.0);
vec2 offsets[9] = vec2[](
vec2(-offset, offset), // top-left
vec2( 0.0f, offset), // top-center
@ -43,24 +47,20 @@ void main()
vec2( 0.0f, -offset), // bottom-center
vec2( offset, -offset) // bottom-right
);
vec2 tex_offset = 1.0 / vec2(800.0, 600.0); // gets size of single texel
vec4 result = vec4(0.0);
vec4 sampleTex[9];
for (int i = 0; i < 9; i++)
{
sampleTex[i] = vec4(texture(screenTexture, texCoord.st + offsets[i]));
}
for (int i = 0; i < 9; i++)
result += sampleTex[i] * edge_kernel[i];
*/
//FragColor = mix(vec4(result), vec4(0.4, 0.0, 0.7, 1.0), 0.2);
if ((effects & (1 << 1)) != 0)
{
result += sampleTex[i] * blur_kernel[i];
//FragColor = mix(texture(screenTexture, texCoord), vec4(1.0, 0.8, 0.0, 1.0), 0.3 - (1.0 / shakeTime) * shakeIntensity);
FragColor = texture(screenTexture, texCoord);
//FragColor = vec4(1.0 / blurDuration, 1.0, 0.0, 1.0);
FragColor = vec4(result);
}
else
{
//FragColor = vec4(1.0, 0.0, 1.0 / blurDuration, 1.0);
FragColor = texture(screenTexture, texCoord);
}
}

View file

@ -7,14 +7,16 @@ layout (std140) uniform uPostProcess {
int dt;
vec3 colorMod;
float blurIntensity;
float blurDuration;
float shakeIntensity;
float shakeTime;
float shakeDuration;
int effects;
vec3 colorMod_hud;
float blurIntensity_hud;
float blurDuration_hud;
float shakeIntensity_hud;
float shakeTime_hud;
float shakeDuration_hud;
int effects_hud;
};
@ -48,8 +50,8 @@ void main()
//SHAKE
if ((effects_hud & (1 << 1)) != 0)
{
gl_Position.x += cos(shakeTime_hud - 90) * 0.01;
gl_Position.y += cos(shakeTime_hud - 80) * 0.01;
gl_Position.x += cos(dt - 90) * shakeIntensity_hud;
gl_Position.y += cos(dt - 80) * shakeIntensity_hud;
}
}
}

View file

@ -4,10 +4,12 @@
#include <SDL_Timer.h>
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <limits>
#include <memory>
#include <utility/resourcemanager.h>
#include <graphics/shader.h>
#include <utility/logger.h>
#include <util.h>
class Postprocessor
{
@ -22,7 +24,8 @@ public:
GREYSCALE = 1 << 4
};
void ApplyEffect(EFFECT effect, float intensity=0.f, float effectDuration=0.f, glm::vec3 colorModifer=glm::vec3(0.0f));
void ApplyEffect(EFFECT effect, float intensity=0.f, float effectDuration=UTIL::INF_TIME, glm::vec3 colorModifer=glm::vec3(0.0f));
void RemoveEffects(EFFECT effect);
void RemoveAllEffects();
@ -49,17 +52,20 @@ private:
alignas(4) int dt;
alignas(16) glm::vec3 colorMod;
alignas(4) float blurIntensity;
alignas(4) float blurDuration;
alignas(4) float shakeIntensity;
alignas(4) float shakeTime;
alignas(4) float shakeDuration;
alignas(4) int curEffects;
// hud
alignas(16) glm::vec3 colorMod_hud;
alignas(4) float blurIntensity_hud;
alignas(4) float blurDuration_hud;
alignas(4) float shakeIntensity_hud;
alignas(4) float shakeTime_hud;
alignas(4) float shakeDuration_hud;
alignas(4) int curEffects_hud;
}postProcessData;
void tickEffectTime(bool worldOrHud);
unsigned int lastTime;
Shader* postProcessShader;
};

View file

@ -6,6 +6,8 @@
namespace UTIL
{
constexpr float INF_TIME = -99.6875f;
void flip_surface(SDL_Surface* surface);
class RandomGenerator

View file

@ -103,6 +103,14 @@ public:
float duration;
};
class ScreenBlurEvent : public Event {
public:
ScreenBlurEvent(float intensity, float duration) : intensity(intensity), duration(duration) {}
std::string getType() const override { return "OnScreenBlur"; }
float intensity;
float duration;
};
class EventManager {
public:
using EventCallback = std::function<void(std::shared_ptr<Event>)>;

View file

@ -100,6 +100,7 @@ void GameActor::fireWeapon()const {
if (sceneContext->getPlayerID() == entityid) {
if (auto gEvent = sceneContext->getGlobalEventManager().lock()) {
gEvent->notify(std::make_shared<ScreenShakeEvent>(0.01f, 0.8f));
gEvent->notify(std::make_shared<ScreenBlurEvent>(1.f, 0.8f));
}
}
}

View file

@ -1,5 +1,6 @@
#include "graphics/postprocess.h"
#include <graphics/quad.h>
#include <util.h>
Postprocessor::Postprocessor(const std::shared_ptr<ResourceManager>& resourceManager)
{
@ -40,9 +41,10 @@ void Postprocessor::ApplyEffect(EFFECT effect, float intensity, float effectDura
postProcessData.curEffects |= effect;
if ((effect & EFFECT::BLUR) != 0) {
postProcessData.blurIntensity = intensity;
postProcessData.blurDuration = effectDuration;
} else if ((effect & EFFECT::SHAKE) != 0) {
postProcessData.shakeIntensity = intensity;
postProcessData.shakeTime = effectDuration;
postProcessData.shakeDuration = effectDuration;
}
if ((effect & EFFECT::COLORMOD) != 0) {
postProcessData.colorMod = colorModifer;
@ -67,18 +69,8 @@ void Postprocessor::applyPostProcess(bool worldOrHud)
postProcessData.curTime = curTime;
postProcessData.dt = curTime - lastTime;
auto subtractTime = [](float remaining, unsigned int dt){
if ((remaining - 1.0f / static_cast<float>(dt)) <= 0.0f)
return 0.0f;
return remaining - (1.0f / static_cast<float>(dt));
};
if (!worldOrHud)
postProcessData.shakeTime = subtractTime(postProcessData.shakeTime, postProcessData.dt);
else
postProcessData.shakeTime_hud = subtractTime(postProcessData.shakeTime_hud, postProcessData.dt);
if (postProcessData.shakeTime <= 0.0f) {
RemoveEffects(SHAKE);
}
tickEffectTime(worldOrHud);
LOG(DEBUG, "Blur duration: {}", postProcessData.blurDuration);
postProcessShader->use();
postProcessShader->setBool("worldOrHud", worldOrHud);
@ -86,17 +78,43 @@ void Postprocessor::applyPostProcess(bool worldOrHud)
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(PostProcessData_t), &postProcessData);
/*
PostProcessData_t* pp_data = (PostProcessData_t*)glMapBuffer(
GL_UNIFORM_BUFFER,
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
if (pp_data) {
std::memcpy(pp_data, &postProcessData, sizeof(PostProcessData_t));
glUnmapBuffer(GL_UNIFORM_BUFFER);
}
*/
glBindBuffer(GL_UNIFORM_BUFFER, 0);
lastTime = curTime;
}
void Postprocessor::tickEffectTime(bool worldOrHud)
{
auto subtractTime = [](float remaining, float dt){
if (remaining == UTIL::INF_TIME) {
return remaining;
}
else if ((remaining - 1.0f / dt) <= 0.0f)
return 0.0f;
return remaining - (1.0f / dt);
};
auto checkToRemove = [](float timeLeft) {
return timeLeft != UTIL::INF_TIME && timeLeft <= 0.f; // checking if the duration is not INF_TIME and is leq than 0.0f
};
// !!! FIX THIS, IT WORKS BUT NOT A SCALABLE SOLUTION !!!
float dt = static_cast<float>(postProcessData.dt);
if (worldOrHud) {
postProcessData.blurDuration_hud = subtractTime(postProcessData.blurDuration_hud, dt);
postProcessData.shakeDuration_hud = subtractTime(postProcessData.shakeDuration_hud, dt);
if (checkToRemove(postProcessData.blurDuration_hud)) {
//RemoveEffects(BLUR);
}
if (checkToRemove(postProcessData.shakeDuration_hud)) {
//RemoveEffects(SHAKE);
}
} else {
postProcessData.blurDuration = subtractTime(postProcessData.blurDuration, dt);
postProcessData.shakeDuration = subtractTime(postProcessData.shakeDuration, dt);
if (checkToRemove(postProcessData.blurDuration)) {
RemoveEffects(BLUR);
}
if (checkToRemove(postProcessData.shakeDuration)) {
RemoveEffects(SHAKE);
}
}
}

View file

@ -29,6 +29,13 @@ void Renderer::hookEventManager(std::weak_ptr<EventManager> eventManager)
shakeEvent->duration
);
});
e->subscribe("OnScreenBlur", [this](std::shared_ptr<Event> event) {
auto blurEvent = std::dynamic_pointer_cast<ScreenBlurEvent>(event);
postProcessor->ApplyEffect(Postprocessor::BLUR,
blurEvent->intensity,
blurEvent->duration
);
});
}
}