feat(render3d): HDR10 output, and DLSS that stays still
HDR output: an HDR10 swapchain (A2B10G10R10, ST 2084 over BT.2020) when the setting asks and the display offers it, with HDR metadata. The tonemap's HDR10 variant keeps the SDR picture up to a 200-nit paper white and rolls highlights on to 1000 nits; the overlay's converts the interface to the same white. The screen and LDR images go 10-bit with it; screenshots refuse while it is on. OpenGL and the Vulkan SDR frame are unchanged. The instance asks for VK_EXT_swapchain_colorspace. HDR metadata only where the loader has vkSetHdrMetadataEXT: Streamline's interposer does not, and calling the thunk crashed the game the moment the swapchain came up HDR10. PC 4K monitor: HDR10, validation 0. R3D_HDR overrides the setting. DLSS: - the vertical jitter offset flips with Streamline's image (rows from the top): unflipped, Quality resolved the ground into concentric rings; - preset K in every mode: the default M put Performance at 18 ms a frame at 4K on an RTX 3070 Ti (33 fps against 41 with DLSS off; with K, 60); - the camera is jittered only while this frame holds a token and the last evaluate worked. R3D_DLSS_PRESET, R3D_CAM_LOG (the camera and DLSS state a frame) and R3D_NOGRAIN for measuring. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
0224af64ab
commit
6525c11b3c
16 changed files with 273 additions and 29 deletions
|
|
@ -6,6 +6,18 @@ in vec4 v_col;
|
|||
uniform sampler2D u_tex;
|
||||
uniform sampler2D u_font;
|
||||
out vec4 o_color;
|
||||
#ifdef HDR10
|
||||
// the interface is sRGB: drawn into an HDR10 frame it sits at paper white, as the picture's white does
|
||||
const float HDR_PAPER = 200.0;
|
||||
vec3 bt709_to_2020(vec3 c) {
|
||||
return mat3(0.6274, 0.0691, 0.0164, 0.3293, 0.9195, 0.0880, 0.0433, 0.0114, 0.8956) * c;
|
||||
}
|
||||
vec3 pq_encode(vec3 nits) {
|
||||
const float m1 = 0.1593017578125, m2 = 78.84375, c1 = 0.8359375, c2 = 18.8515625, c3 = 18.6875;
|
||||
vec3 yp = pow(clamp(nits / 10000.0, 0.0, 1.0), vec3(m1));
|
||||
return pow((c1 + c2 * yp) / (1.0 + c3 * yp), vec3(m2));
|
||||
}
|
||||
#endif
|
||||
void main() {
|
||||
float mode = floor((v_uv.y + 0.5) * 0.25);
|
||||
vec2 uv = vec2(v_uv.x, v_uv.y - 4.0 * mode);
|
||||
|
|
@ -17,4 +29,7 @@ void main() {
|
|||
vec4 t = texture(u_tex, uv);
|
||||
o_color = vec4(v_col.rgb * t.rgb, v_col.a * t.a);
|
||||
}
|
||||
#ifdef HDR10
|
||||
o_color.rgb = pq_encode(bt709_to_2020(pow(max(o_color.rgb, vec3(0.0)), vec3(2.2))) * HDR_PAPER);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
BIN
packages/ludic.render3d/shaders/spv/a4683767.frag.spv
Normal file
BIN
packages/ludic.render3d/shaders/spv/a4683767.frag.spv
Normal file
Binary file not shown.
BIN
packages/ludic.render3d/shaders/spv/a4683767.vert.spv
Normal file
BIN
packages/ludic.render3d/shaders/spv/a4683767.vert.spv
Normal file
Binary file not shown.
BIN
packages/ludic.render3d/shaders/spv/e86f78e8.frag.spv
Normal file
BIN
packages/ludic.render3d/shaders/spv/e86f78e8.frag.spv
Normal file
Binary file not shown.
BIN
packages/ludic.render3d/shaders/spv/e86f78e8.vert.spv
Normal file
BIN
packages/ludic.render3d/shaders/spv/e86f78e8.vert.spv
Normal file
Binary file not shown.
|
|
@ -577,6 +577,57 @@ T 725523d9 u_prefilter 8
|
|||
T 725523d9 u_shadow 9
|
||||
T 725523d9 u_tershadow 10
|
||||
T 725523d9 u_ts_height 11
|
||||
P a4683767 fullscreen.vert tonemap.frag #define HDR10;
|
||||
B a4683767 frag 1 852
|
||||
U a4683767 frag u_cascade_vp 0 mat4 5 64
|
||||
U a4683767 frag u_cascade_split 320 float 5 16
|
||||
U a4683767 frag u_cascade_range 400 float 5 16
|
||||
U a4683767 frag u_cascade_texel 480 float 5 16
|
||||
U a4683767 frag u_sun_dir 560 vec3 1 0
|
||||
U a4683767 frag u_sun_color 576 vec3 1 0
|
||||
U a4683767 frag u_cam_pos 592 vec3 1 0
|
||||
U a4683767 frag u_prefilter_levels 604 float 1 0
|
||||
U a4683767 frag u_fog_density 608 float 1 0
|
||||
U a4683767 frag u_fog_height_falloff 612 float 1 0
|
||||
U a4683767 frag u_fog_base 616 float 1 0
|
||||
U a4683767 frag u_clip_y 620 float 1 0
|
||||
U a4683767 frag u_spec_scale 624 float 1 0
|
||||
U a4683767 frag u_sky_rot 632 vec2 1 0
|
||||
U a4683767 frag u_ibl_scale 640 vec3 1 0
|
||||
U a4683767 frag u_daylight 652 float 1 0
|
||||
U a4683767 frag u_fire_pos 656 vec3 1 0
|
||||
U a4683767 frag u_fire_color 672 vec3 1 0
|
||||
U a4683767 frag u_hand_pos 688 vec3 1 0
|
||||
U a4683767 frag u_hand_color 704 vec3 1 0
|
||||
U a4683767 frag u_hand_dir 720 vec3 1 0
|
||||
U a4683767 frag u_hand_cone 732 float 1 0
|
||||
U a4683767 frag u_ts_origin 736 vec2 1 0
|
||||
U a4683767 frag u_ts_half 744 float 1 0
|
||||
U a4683767 frag u_ts_on 748 float 1 0
|
||||
U a4683767 frag u_force_cascade 752 int 1 0
|
||||
U a4683767 frag u_cloud_shadow 756 float 1 0
|
||||
U a4683767 frag u_time 760 float 1 0
|
||||
U a4683767 frag u_ao_strength 764 float 1 0
|
||||
U a4683767 frag u_gi_strength 768 float 1 0
|
||||
U a4683767 frag u_wb 784 vec3 1 0
|
||||
U a4683767 frag u_lift 800 vec3 1 0
|
||||
U a4683767 frag u_gain 816 vec3 1 0
|
||||
U a4683767 frag u_exposure 828 float 1 0
|
||||
U a4683767 frag u_auto 832 float 1 0
|
||||
U a4683767 frag u_bloom_strength 836 float 1 0
|
||||
U a4683767 frag u_vignette 840 float 1 0
|
||||
U a4683767 frag u_saturation 844 float 1 0
|
||||
U a4683767 frag u_contrast 848 float 1 0
|
||||
T a4683767 u_adapt 2
|
||||
T a4683767 u_ao 3
|
||||
T a4683767 u_bloom 4
|
||||
T a4683767 u_brdf 5
|
||||
T a4683767 u_hdr 6
|
||||
T a4683767 u_irradiance 7
|
||||
T a4683767 u_prefilter 8
|
||||
T a4683767 u_shadow 9
|
||||
T a4683767 u_tershadow 10
|
||||
T a4683767 u_ts_height 11
|
||||
P 7ed7de52 grass.vert model.frag #define FOLIAGE;#define BLADE;
|
||||
B 7ed7de52 vert 0 296
|
||||
U 7ed7de52 vert u_view 0 mat4 1 0
|
||||
|
|
@ -1808,6 +1859,49 @@ T 1b654972 u_shadow 6
|
|||
T 1b654972 u_tershadow 7
|
||||
T 1b654972 u_tex 8
|
||||
T 1b654972 u_ts_height 9
|
||||
P e86f78e8 overlay.vert overlay.frag #define HDR10;
|
||||
B e86f78e8 vert 0 8
|
||||
U e86f78e8 vert u_screen 0 vec2 1 0
|
||||
I e86f78e8 a_pos 0 vec2
|
||||
I e86f78e8 a_uv 1 vec2
|
||||
I e86f78e8 a_col 2 vec4
|
||||
B e86f78e8 frag 0 764
|
||||
U e86f78e8 frag u_cascade_vp 0 mat4 5 64
|
||||
U e86f78e8 frag u_cascade_split 320 float 5 16
|
||||
U e86f78e8 frag u_cascade_range 400 float 5 16
|
||||
U e86f78e8 frag u_cascade_texel 480 float 5 16
|
||||
U e86f78e8 frag u_sun_dir 560 vec3 1 0
|
||||
U e86f78e8 frag u_sun_color 576 vec3 1 0
|
||||
U e86f78e8 frag u_cam_pos 592 vec3 1 0
|
||||
U e86f78e8 frag u_prefilter_levels 604 float 1 0
|
||||
U e86f78e8 frag u_fog_density 608 float 1 0
|
||||
U e86f78e8 frag u_fog_height_falloff 612 float 1 0
|
||||
U e86f78e8 frag u_fog_base 616 float 1 0
|
||||
U e86f78e8 frag u_clip_y 620 float 1 0
|
||||
U e86f78e8 frag u_spec_scale 624 float 1 0
|
||||
U e86f78e8 frag u_sky_rot 632 vec2 1 0
|
||||
U e86f78e8 frag u_ibl_scale 640 vec3 1 0
|
||||
U e86f78e8 frag u_daylight 652 float 1 0
|
||||
U e86f78e8 frag u_fire_pos 656 vec3 1 0
|
||||
U e86f78e8 frag u_fire_color 672 vec3 1 0
|
||||
U e86f78e8 frag u_hand_pos 688 vec3 1 0
|
||||
U e86f78e8 frag u_hand_color 704 vec3 1 0
|
||||
U e86f78e8 frag u_hand_dir 720 vec3 1 0
|
||||
U e86f78e8 frag u_hand_cone 732 float 1 0
|
||||
U e86f78e8 frag u_ts_origin 736 vec2 1 0
|
||||
U e86f78e8 frag u_ts_half 744 float 1 0
|
||||
U e86f78e8 frag u_ts_on 748 float 1 0
|
||||
U e86f78e8 frag u_force_cascade 752 int 1 0
|
||||
U e86f78e8 frag u_cloud_shadow 756 float 1 0
|
||||
U e86f78e8 frag u_time 760 float 1 0
|
||||
T e86f78e8 u_brdf 2
|
||||
T e86f78e8 u_font 3
|
||||
T e86f78e8 u_irradiance 4
|
||||
T e86f78e8 u_prefilter 5
|
||||
T e86f78e8 u_shadow 6
|
||||
T e86f78e8 u_tershadow 7
|
||||
T e86f78e8 u_tex 8
|
||||
T e86f78e8 u_ts_height 9
|
||||
P 1fde9cd2 skin.vert model.frag
|
||||
B 1fde9cd2 vert 0 3344
|
||||
U 1fde9cd2 vert u_model 0 mat4 1 0
|
||||
|
|
|
|||
|
|
@ -21,6 +21,19 @@ vec3 aces(vec3 x) {
|
|||
return clamp((x * (a * x + b)) / (x * (c * x + d) + e), 0.0, 1.0);
|
||||
}
|
||||
float hash(vec2 p) { return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453); }
|
||||
#ifdef HDR10
|
||||
// HDR10 output: nits in BT.2020 primaries, encoded with the SMPTE ST 2084 (PQ) curve
|
||||
const float HDR_PAPER = 200.0; // nits the SDR picture's white sits at
|
||||
const float HDR_PEAK = 1000.0; // nits the brightest highlight rolls on to
|
||||
vec3 bt709_to_2020(vec3 c) {
|
||||
return mat3(0.6274, 0.0691, 0.0164, 0.3293, 0.9195, 0.0880, 0.0433, 0.0114, 0.8956) * c;
|
||||
}
|
||||
vec3 pq_encode(vec3 nits) {
|
||||
const float m1 = 0.1593017578125, m2 = 78.84375, c1 = 0.8359375, c2 = 18.8515625, c3 = 18.6875;
|
||||
vec3 yp = pow(clamp(nits / 10000.0, 0.0, 1.0), vec3(m1));
|
||||
return pow((c1 + c2 * yp) / (1.0 + c3 * yp), vec3(m2));
|
||||
}
|
||||
#endif
|
||||
void main() {
|
||||
vec3 hdr = sane(texture(u_hdr, v_uv).rgb);
|
||||
vec4 gi = texture(u_ao, v_uv);
|
||||
|
|
@ -34,14 +47,25 @@ void main() {
|
|||
// filmic contrast around mid grey in log space
|
||||
c = max(c, vec3(0.0));
|
||||
c = pow(c / 0.18, vec3(u_contrast)) * 0.18;
|
||||
vec3 pre = c; // what ACES is about to roll off, kept for HDR highlights
|
||||
c = aces(c);
|
||||
// lift / gain grade in display space
|
||||
c = c * u_gain + u_lift * (1.0 - c);
|
||||
float lum = dot(c, vec3(0.2126, 0.7152, 0.0722));
|
||||
c = mix(vec3(lum), c, u_saturation);
|
||||
vec2 q = v_uv * 2.0 - 1.0;
|
||||
c *= 1.0 - u_vignette * dot(q, q) * 0.5;
|
||||
float vig = 1.0 - u_vignette * dot(q, q) * 0.5;
|
||||
c *= vig;
|
||||
#ifdef HDR10
|
||||
// up to paper white the SDR picture as it is; past it, what ACES clipped runs on to the peak
|
||||
vec3 hi = max(pre - 1.0, vec3(0.0));
|
||||
vec3 nits = (c + hi / (hi + 1.0) * (HDR_PEAK / HDR_PAPER - 1.0) * vig) * HDR_PAPER;
|
||||
vec3 e = pq_encode(bt709_to_2020(nits));
|
||||
e += (hash(gl_FragCoord.xy) - 0.5) / 1023.0;
|
||||
o_color = vec4(e, 1.0);
|
||||
#else
|
||||
c = pow(c, vec3(1.0 / 2.2));
|
||||
c += (hash(gl_FragCoord.xy) - 0.5) / 255.0;
|
||||
o_color = vec4(c, 1.0);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ fullscreen.vert|ssgi.frag|
|
|||
fullscreen.vert|ternormal.frag|
|
||||
fullscreen.vert|tershadow.frag|#define NOISE_ONLY;
|
||||
fullscreen.vert|tonemap.frag|
|
||||
fullscreen.vert|tonemap.frag|#define HDR10;
|
||||
grass.vert|model.frag|#define FOLIAGE;#define BLADE;
|
||||
grass.vert|model.frag|#define FOLIAGE;#define BLADE;#define TILES;
|
||||
impostor.vert|impostor.frag|
|
||||
|
|
@ -37,6 +38,7 @@ model.vert|shadow.frag|#define SHADOW_PASS;
|
|||
model.vert|shadow.frag|#define SHADOW_PASS;#define WIND;
|
||||
model.vert|shadow.frag|#define SHADOW_PASS;#define WIND;#define ALPHA_TEST;
|
||||
overlay.vert|overlay.frag|
|
||||
overlay.vert|overlay.frag|#define HDR10;
|
||||
skin.vert|model.frag|
|
||||
skin.vert|model.frag|#define ALPHA_TEST;
|
||||
skin.vert|outline.frag|#define OUTLINE;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue