mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run
- Motion vectors: single unjittered reprojection matrix (80 bytes) instead of two jittered matrices (160 bytes), eliminating numerical instability from jitter amplification through large world coordinates - Sharpen pass: fix Y-flip for correct UV sampling, double-buffer descriptor sets to avoid race with in-flight command buffers - MSAA: auto-disable when FSR2 enabled, grey out AA setting in UI - Accumulation: variance-based neighborhood clamping in YCoCg space, correct history layout transitions - Frame index: wrap at 256 for stable Halton sequence
50 lines
1.9 KiB
GLSL
50 lines
1.9 KiB
GLSL
#version 450
|
|
|
|
layout(location = 0) in vec2 TexCoord;
|
|
layout(location = 0) out vec4 FragColor;
|
|
|
|
layout(set = 0, binding = 0) uniform sampler2D inputImage;
|
|
|
|
layout(push_constant) uniform PushConstants {
|
|
vec4 params; // x = 1/width, y = 1/height, z = sharpness (0-2), w = unused
|
|
} pc;
|
|
|
|
void main() {
|
|
// Undo the vertex shader Y flip (postprocess.vert flips for Vulkan overlay,
|
|
// but we need standard UV coords for texture sampling)
|
|
vec2 tc = vec2(TexCoord.x, 1.0 - TexCoord.y);
|
|
|
|
vec2 texelSize = pc.params.xy;
|
|
float sharpness = pc.params.z;
|
|
|
|
// RCAS: Robust Contrast-Adaptive Sharpening
|
|
// 5-tap cross pattern
|
|
vec3 center = texture(inputImage, tc).rgb;
|
|
vec3 north = texture(inputImage, tc + vec2(0.0, -texelSize.y)).rgb;
|
|
vec3 south = texture(inputImage, tc + vec2(0.0, texelSize.y)).rgb;
|
|
vec3 west = texture(inputImage, tc + vec2(-texelSize.x, 0.0)).rgb;
|
|
vec3 east = texture(inputImage, tc + vec2( texelSize.x, 0.0)).rgb;
|
|
|
|
// Compute local contrast (min/max of neighborhood)
|
|
vec3 minRGB = min(center, min(min(north, south), min(west, east)));
|
|
vec3 maxRGB = max(center, max(max(north, south), max(west, east)));
|
|
|
|
// Adaptive sharpening weight based on local contrast
|
|
// High contrast = less sharpening (prevent ringing)
|
|
vec3 range = maxRGB - minRGB;
|
|
vec3 rcpRange = 1.0 / (range + 0.001);
|
|
|
|
// Sharpening amount: inversely proportional to contrast
|
|
float luma = dot(center, vec3(0.299, 0.587, 0.114));
|
|
float lumaRange = max(range.r, max(range.g, range.b));
|
|
float w = clamp(1.0 - lumaRange * 2.0, 0.0, 1.0) * sharpness * 0.25;
|
|
|
|
// Apply sharpening via unsharp mask
|
|
vec3 avg = (north + south + west + east) * 0.25;
|
|
vec3 sharpened = center + (center - avg) * w;
|
|
|
|
// Clamp to prevent ringing artifacts
|
|
sharpened = clamp(sharpened, minRGB, maxRGB);
|
|
|
|
FragColor = vec4(sharpened, 1.0);
|
|
}
|