mirror of
https://github.com/valentderah/totk-pc-recomp.git
synced 2026-11-11 01:41:02 +00:00
With hdr = 1 the game's tonemap shader is replaced by one that keeps highlights up to the display's peak, the present reads the float picture the game copies into its 8-bit window texture, and a compute pass encodes it as PQ in Rec. 2020 for an HDR10 swapchain. Peak, paper white and HUD brightness are live settings in the menu and totk.ini. The approach follows the RenoDX TotK mod by souperman9 and Musa; no code was copied. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
35 lines
1.6 KiB
Plaintext
35 lines
1.6 KiB
Plaintext
#version 450
|
|
// HDR10 encode on the present (runtime/vk_hdr.c vk_hdr_encode): the game's picture, crop rectangle at offset, linear
|
|
// Rec. 709 with the HUD's white at 1.0 (an sRGB view decodes the 8-bit window texture), into an RGBA16F image of PQ
|
|
// code values in Rec. 2020 that FSR 1 or the blit then scale into the HDR10 swapchain. p.x: nits of 1.0, p.y: the
|
|
// display's peak in nits, p.z: 1 when the source holds sRGB-encoded values in a UNORM format.
|
|
// PQ: SMPTE ST 2084; the Rec. 709 to Rec. 2020 matrix: ITU-R BT.2087.
|
|
layout(local_size_x = 8, local_size_y = 8) in;
|
|
layout(binding = 0) uniform sampler2D src;
|
|
layout(binding = 1, rgba16f) uniform writeonly image2D dst;
|
|
layout(push_constant) uniform P {
|
|
ivec2 offset;
|
|
ivec2 size;
|
|
vec4 p;
|
|
} pc;
|
|
|
|
vec3 srgb_decode(vec3 c) {
|
|
return mix(c / 12.92, pow((c + 0.055) / 1.055, vec3(2.4)), greaterThan(c, vec3(0.04045)));
|
|
}
|
|
|
|
vec3 pq(vec3 nits) {
|
|
const float m1 = 0.1593017578125, m2 = 78.84375, c1 = 0.8359375, c2 = 18.8515625, c3 = 18.6875;
|
|
vec3 y = pow(clamp(nits / 10000.0, 0.0, 1.0), vec3(m1));
|
|
return pow((c1 + c2 * y) / (1.0 + c3 * y), vec3(m2));
|
|
}
|
|
|
|
void main() {
|
|
ivec2 at = ivec2(gl_GlobalInvocationID.xy);
|
|
if (any(greaterThanEqual(at, pc.size))) return;
|
|
vec3 c = max(texelFetch(src, at + pc.offset, 0).rgb, vec3(0.0));
|
|
if (pc.p.z > 0.5) c = srgb_decode(clamp(c, 0.0, 1.0));
|
|
const mat3 to2020 = mat3(0.6274, 0.0691, 0.0164, 0.3293, 0.9195, 0.0880, 0.0433, 0.0114, 0.8956);
|
|
vec3 nits = min(max(to2020 * c, vec3(0.0)) * pc.p.x, vec3(pc.p.y));
|
|
imageStore(dst, at, vec4(pq(nits), 1.0));
|
|
}
|