mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-24 08:00:14 +00:00
Implement FSR 2.2 temporal upscaling
Full FSR 2.2 pipeline with depth-based motion vector reprojection, temporal accumulation with YCoCg neighborhood clamping, and RCAS contrast-adaptive sharpening. Architecture (designed for FSR 3.x frame generation readiness): - Camera: Halton(2,3) sub-pixel jitter with unjittered projection stored separately for motion vector computation - Motion vectors: compute shader reconstructs world position from depth + inverse VP, reprojects with previous frame's VP - Temporal accumulation: compute shader blends 5-10% current frame with 90-95% clamped history, adaptive blend for disocclusion - History: ping-pong R16G16B16A16 buffers at display resolution - Sharpening: RCAS fragment pass with contrast-adaptive weights Integration: - FSR2 replaces both FSR1 and MSAA when enabled - Scene renders to internal resolution framebuffer (no MSAA) - Compute passes run between scene and swapchain render passes - Camera cut detection resets history on teleport - Quality presets shared with FSR1 (0.50-0.77 scale factors) - UI: "Upscaling" combo with Off/FSR 1.0/FSR 2.2 options
This commit is contained in:
parent
0ffeabd4ed
commit
52317d1edd
11 changed files with 957 additions and 12 deletions
|
|
@ -20,6 +20,13 @@ void Camera::updateProjectionMatrix() {
|
|||
projectionMatrix = glm::perspective(glm::radians(fov), aspectRatio, nearPlane, farPlane);
|
||||
// Vulkan clip-space has Y pointing down; flip the projection's Y axis.
|
||||
projectionMatrix[1][1] *= -1.0f;
|
||||
unjitteredProjectionMatrix = projectionMatrix;
|
||||
|
||||
// Re-apply jitter if active
|
||||
if (jitterOffset.x != 0.0f || jitterOffset.y != 0.0f) {
|
||||
projectionMatrix[2][0] += jitterOffset.x;
|
||||
projectionMatrix[2][1] += jitterOffset.y;
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 Camera::getForward() const {
|
||||
|
|
@ -40,6 +47,21 @@ glm::vec3 Camera::getUp() const {
|
|||
return glm::normalize(glm::cross(getRight(), getForward()));
|
||||
}
|
||||
|
||||
void Camera::setJitter(float jx, float jy) {
|
||||
// Remove old jitter, apply new
|
||||
projectionMatrix[2][0] -= jitterOffset.x;
|
||||
projectionMatrix[2][1] -= jitterOffset.y;
|
||||
jitterOffset = glm::vec2(jx, jy);
|
||||
projectionMatrix[2][0] += jitterOffset.x;
|
||||
projectionMatrix[2][1] += jitterOffset.y;
|
||||
}
|
||||
|
||||
void Camera::clearJitter() {
|
||||
projectionMatrix[2][0] -= jitterOffset.x;
|
||||
projectionMatrix[2][1] -= jitterOffset.y;
|
||||
jitterOffset = glm::vec2(0.0f);
|
||||
}
|
||||
|
||||
Ray Camera::screenToWorldRay(float screenX, float screenY, float screenW, float screenH) const {
|
||||
float ndcX = (2.0f * screenX / screenW) - 1.0f;
|
||||
// Vulkan Y-flip is baked into projectionMatrix, so NDC Y maps directly:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue