mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
feat: add ghost mode grayscale screen effect
- FXAA path: repurpose _pad field as 'desaturate' push constant; when ghostMode_ is true, convert final pixel to grayscale with slight cool blue tint using luma(0.299,0.587,0.114) mix - Non-FXAA path: apply a high-opacity gray overlay (rgba 0.5,0.5,0.55,0.82) over the scene for a washed-out look - Both parallel (SEC_POST) and single-threaded render paths covered - ghostMode_ flag set each frame from gameHandler->isPlayerGhost()
This commit is contained in:
parent
d3159791de
commit
acf99354b3
4 changed files with 26 additions and 5 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// FXAA 3.11 — Fast Approximate Anti-Aliasing post-process pass.
|
||||
// Reads the resolved scene color and outputs a smoothed result.
|
||||
// Push constant: rcpFrame = vec2(1/width, 1/height), sharpness (0=off, 2=max), unused.
|
||||
// Push constant: rcpFrame = vec2(1/width, 1/height), sharpness (0=off, 2=max), desaturate (1=ghost grayscale).
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D uScene;
|
||||
|
||||
|
|
@ -11,8 +11,8 @@ layout(location = 0) out vec4 outColor;
|
|||
|
||||
layout(push_constant) uniform PC {
|
||||
vec2 rcpFrame;
|
||||
float sharpness; // 0 = no sharpen, 2 = max (matches FSR2 RCAS range)
|
||||
float _pad;
|
||||
float sharpness; // 0 = no sharpen, 2 = max (matches FSR2 RCAS range)
|
||||
float desaturate; // 1 = full grayscale (ghost mode), 0 = normal color
|
||||
} pc;
|
||||
|
||||
// Quality tuning
|
||||
|
|
@ -145,5 +145,11 @@ void main() {
|
|||
fxaaResult = clamp(fxaaResult + s * (fxaaResult - blur), 0.0, 1.0);
|
||||
}
|
||||
|
||||
// Ghost mode: desaturate to grayscale (with a slight cool blue tint).
|
||||
if (pc.desaturate > 0.5) {
|
||||
float gray = dot(fxaaResult, vec3(0.299, 0.587, 0.114));
|
||||
fxaaResult = mix(fxaaResult, vec3(gray, gray, gray * 1.05), pc.desaturate);
|
||||
}
|
||||
|
||||
outColor = vec4(fxaaResult, 1.0);
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -638,6 +638,8 @@ private:
|
|||
bool terrainEnabled = true;
|
||||
bool terrainLoaded = false;
|
||||
|
||||
bool ghostMode_ = false; // set each frame from gameHandler->isPlayerGhost()
|
||||
|
||||
// CPU timing stats (last frame/update).
|
||||
double lastUpdateMs = 0.0;
|
||||
double lastRenderMs = 0.0;
|
||||
|
|
|
|||
|
|
@ -5044,7 +5044,7 @@ void Renderer::renderFXAAPass() {
|
|||
vkCmdBindDescriptorSets(currentCmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
fxaa_.pipelineLayout, 0, 1, &fxaa_.descSet, 0, nullptr);
|
||||
|
||||
// Pass rcpFrame + sharpness (vec4, 16 bytes).
|
||||
// Pass rcpFrame + sharpness + desaturate (vec4, 16 bytes).
|
||||
// When FSR2/FSR3 is active alongside FXAA, forward FSR2's sharpness so the
|
||||
// post-FXAA unsharp-mask step restores the crispness that FXAA's blur removes.
|
||||
float sharpness = fsr2_.enabled ? fsr2_.sharpness : 0.0f;
|
||||
|
|
@ -5052,7 +5052,7 @@ void Renderer::renderFXAAPass() {
|
|||
1.0f / static_cast<float>(ext.width),
|
||||
1.0f / static_cast<float>(ext.height),
|
||||
sharpness,
|
||||
0.0f
|
||||
ghostMode_ ? 1.0f : 0.0f // desaturate: 1=ghost grayscale, 0=normal
|
||||
};
|
||||
vkCmdPushConstants(currentCmd, fxaa_.pipelineLayout,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, pc);
|
||||
|
|
@ -5092,6 +5092,9 @@ void Renderer::renderWorld(game::World* world, game::GameHandler* gameHandler) {
|
|||
lastWMORenderMs = 0.0;
|
||||
lastM2RenderMs = 0.0;
|
||||
|
||||
// Cache ghost state for use in overlay and FXAA passes this frame.
|
||||
ghostMode_ = (gameHandler && gameHandler->isPlayerGhost());
|
||||
|
||||
uint32_t frameIdx = vkCtx->getCurrentFrame();
|
||||
VkDescriptorSet perFrameSet = perFrameDescSets[frameIdx];
|
||||
const glm::mat4& view = camera ? camera->getViewMatrix() : glm::mat4(1.0f);
|
||||
|
|
@ -5237,6 +5240,12 @@ void Renderer::renderWorld(game::World* world, game::GameHandler* gameHandler) {
|
|||
renderOverlay(tint, cmd);
|
||||
}
|
||||
}
|
||||
// Ghost mode desaturation overlay (non-FXAA path approximation).
|
||||
// When FXAA is active the FXAA shader applies true per-pixel desaturation;
|
||||
// otherwise a high-opacity gray overlay gives a similar washed-out effect.
|
||||
if (ghostMode_ && overlayPipeline && !fxaa_.enabled) {
|
||||
renderOverlay(glm::vec4(0.5f, 0.5f, 0.55f, 0.82f), cmd);
|
||||
}
|
||||
if (minimap && minimap->isEnabled() && camera && window) {
|
||||
glm::vec3 minimapCenter = camera->getPosition();
|
||||
if (cameraController && cameraController->isThirdPerson())
|
||||
|
|
@ -5369,6 +5378,10 @@ void Renderer::renderWorld(game::World* world, game::GameHandler* gameHandler) {
|
|||
renderOverlay(tint);
|
||||
}
|
||||
}
|
||||
// Ghost mode desaturation overlay (non-FXAA path approximation).
|
||||
if (ghostMode_ && overlayPipeline && !fxaa_.enabled) {
|
||||
renderOverlay(glm::vec4(0.5f, 0.5f, 0.55f, 0.82f));
|
||||
}
|
||||
if (minimap && minimap->isEnabled() && camera && window) {
|
||||
glm::vec3 minimapCenter = camera->getPosition();
|
||||
if (cameraController && cameraController->isThirdPerson())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue