mirror of
https://github.com/FelipePrado0/SpartanPort.git
synced 2026-11-07 10:45:59 -10:00
Frame captures show the depth of field as a chain of 480x270 passes that blur the scene colour, read by the final composite (pixel shader 1b4f84d1cc5f5f9e, the first draw of the pass writing the display buffer). The composite maps the linear depth to a distance from the focus and turns that into four ramps that mix the sharp colour and the blurred ones. With "Depth of field" off the distance's scale and bias and the four ramp slopes in its 80 byte constant buffer are set to zero, so every pixel gets the in-focus weights and the sharp colour is returned. The change is made on the copy the GPU reads (the constant ring of the draw pipeline, else a stream buffer copy), and only when the constants have the captured shape. On (the default) nothing changes. - spartanport.ini: depth_of_field (default 1); env override SPARTAN_DEPTH_OF_FIELD. Live. - In-game menu and launcher (Graphics > Effects), with pt/es/zh/id texts. - The constants and the change are in gpu/shim/spartanport_depth_of_field.h with a test (tests/test_depth_of_field.cpp); the setting is covered in tests/test_graphics_settings.cpp. Not run in game yet: the constants come from captures of one scene. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01XtU1iHgWpXde4Af9YrW3Y6
51 lines
1.9 KiB
C++
51 lines
1.9 KiB
C++
// The depth of field switch (gpu/shim/spartanport_depth_of_field.h): no GPU or game dump needed.
|
|
#include <array>
|
|
#include <cassert>
|
|
#include <cstdio>
|
|
#include "spartanport_depth_of_field.h"
|
|
|
|
int main() {
|
|
namespace D = SpartanDepthOfField;
|
|
|
|
// Which buffer: the composite's first stage buffer, 80 bytes.
|
|
assert(D::IsComposite(D::Composite, 0, 80));
|
|
assert(!D::IsComposite(D::Composite, 1, 80));
|
|
assert(!D::IsComposite(D::Composite, 0, 64));
|
|
assert(!D::IsComposite(0x1234, 0, 80));
|
|
|
|
// The constants of a frame capture of the game (book camera scene).
|
|
const std::array<float, D::ConstantWords> captured = {
|
|
0.00769231f, -0.711538f, 0.5f, 0.0f, -3.0303f, -3.0303f, -2.94118f,
|
|
2.94118f, 1.0f, 2.0f, 2.94118f, -1.94118f, 0.000260417f, -0.00138889f,
|
|
-0.00078125f, -0.000462963f, -0.000260417f, 0.00138889f, 0.00078125f, 0.000462963f};
|
|
static_assert(sizeof(captured) == D::ConstantBytes);
|
|
|
|
auto changed = captured;
|
|
assert(D::Disable(changed.data()));
|
|
// The distance's scale and bias and the four ramp slopes are zero, nothing else moved.
|
|
for (size_t i = 0; i < changed.size(); ++i) {
|
|
const bool zeroed = i < 2 || (i >= 4 && i < 8);
|
|
assert(changed[i] == (zeroed ? 0.0f : captured[i]));
|
|
}
|
|
// Already changed: no longer the game's shape, left alone.
|
|
auto again = changed;
|
|
assert(!D::Disable(again.data()));
|
|
assert(again == changed);
|
|
|
|
// Anything of another shape is not touched.
|
|
std::array<float, D::ConstantWords> other{};
|
|
assert(!D::Disable(other.data()));
|
|
other = captured;
|
|
other[4] = 3.0f; // a ramp that rises
|
|
auto before = other;
|
|
assert(!D::Disable(other.data()));
|
|
assert(other == before);
|
|
other = captured;
|
|
other[8] = 0.0f; // the first ramp's offset
|
|
before = other;
|
|
assert(!D::Disable(other.data()));
|
|
assert(other == before);
|
|
|
|
std::puts("Depth of field tests passed");
|
|
}
|