mirror of
https://github.com/FelipePrado0/SpartanPort.git
synced 2026-11-07 10:45:59 -10:00
The blur is a short chain of passes found in a frame capture: a half resolution pass draws a velocity image, one draw blurs the half resolution scene colour along it (ps 107d87f9d56574cf) and the next draw blends the result back over the full resolution scene colour (ps abd418f2b4587d5d, the blended use of a plain copy shader). With "Motion blur" off those two draws are skipped, so the scene colour is left as the game rendered it. On (the default) nothing changes. - spartanport.ini: motion_blur (default 1); env override SPARTAN_MOTION_BLUR. Live. - In-game menu (Graphics > Effects) and launcher (Graphics > Effects), with pt/es/zh texts. - The skip rule is in gpu/shim/spartanport_motion_blur.h with its own test (tests/test_motion_blur.cpp); the setting is covered in tests/test_graphics_settings.cpp. - The log notes the first skipped draw of each kind (Motion blur: off, skipping ...). Not run on a real game yet: the hashes come from one capture of CUSA01623 01.02. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01XtU1iHgWpXde4Af9YrW3Y6
55 lines
2.7 KiB
C++
55 lines
2.7 KiB
C++
// The motion blur skip rule (gpu/shim/spartanport_motion_blur.h): no GPU or game dump needed.
|
|
#include <cassert>
|
|
#include <cstdio>
|
|
#include "spartanport_motion_blur.h"
|
|
|
|
int main() {
|
|
using SpartanMotionBlur::Action;
|
|
using SpartanMotionBlur::BlurPass;
|
|
using SpartanMotionBlur::Composite;
|
|
constexpr std::uint64_t Other = 0x1234;
|
|
|
|
{
|
|
// On: nothing is skipped, whatever the shaders are.
|
|
SpartanMotionBlur::Rule rule;
|
|
assert(rule.Next(Other, false, false) == Action::Draw);
|
|
assert(rule.Next(BlurPass, false, false) == Action::Draw);
|
|
assert(rule.Next(Composite, true, false) == Action::Draw);
|
|
assert(rule.Next(Composite, false, false) == Action::Draw);
|
|
}
|
|
{
|
|
// Off: the blur draw and the blended copy right after it go, everything else stays.
|
|
SpartanMotionBlur::Rule rule;
|
|
assert(rule.Next(Other, false, true) == Action::Draw);
|
|
assert(rule.Next(Composite, false, true) == Action::Draw); // the copy without blending
|
|
assert(rule.Next(Composite, true, true) == Action::Draw); // blended, but no blur before it
|
|
assert(rule.Next(BlurPass, false, true) == Action::SkipBlur);
|
|
assert(rule.Next(Composite, true, true) == Action::SkipComposite);
|
|
assert(rule.Next(Composite, true, true) == Action::Draw); // only the one after the blur
|
|
assert(rule.Next(BlurPass, false, true) == Action::SkipBlur);
|
|
assert(rule.Next(BlurPass, false, true) == Action::SkipBlur); // a second blur draw
|
|
assert(rule.Next(Composite, true, true) == Action::SkipComposite);
|
|
}
|
|
{
|
|
// A draw between the two ends the wait: the copy after it is drawn.
|
|
SpartanMotionBlur::Rule rule;
|
|
assert(rule.Next(BlurPass, false, true) == Action::SkipBlur);
|
|
assert(rule.Next(Other, true, true) == Action::Draw);
|
|
assert(rule.Next(Composite, true, true) == Action::Draw);
|
|
// The copy without blending directly after the blur is not the composite either.
|
|
assert(rule.Next(BlurPass, false, true) == Action::SkipBlur);
|
|
assert(rule.Next(Composite, false, true) == Action::Draw);
|
|
assert(rule.Next(Composite, true, true) == Action::Draw);
|
|
}
|
|
{
|
|
// Switched on between the two draws: the copy of the skipped blur is still skipped (it
|
|
// would blend a picture nobody drew), and the next blur is drawn.
|
|
SpartanMotionBlur::Rule rule;
|
|
assert(rule.Next(BlurPass, false, true) == Action::SkipBlur);
|
|
assert(rule.Next(Composite, true, false) == Action::SkipComposite);
|
|
assert(rule.Next(BlurPass, false, false) == Action::Draw);
|
|
assert(rule.Next(Composite, true, false) == Action::Draw);
|
|
}
|
|
std::puts("Motion blur rule tests passed");
|
|
}
|