diff --git a/presets/crt-royale-kurozumi.slangp b/presets/crt-royale-kurozumi.slangp index ca9627a..7889984 100755 --- a/presets/crt-royale-kurozumi.slangp +++ b/presets/crt-royale-kurozumi.slangp @@ -22,7 +22,7 @@ shaders = "13" # Load an aperture grille, slot mask, and an EDP shadow mask, and load a small # non-mipmapped version and a large mipmapped version. # TODO: Test masks in other directories. -textures = "mask_grille_texture_small;mask_grille_texture_large;mask_slot_texture_small;mask_slot_texture_large;mask_shadow_texture_small;mask_shadow_texture_large;SamplerLUT" +textures = "mask_grille_texture_small;mask_grille_texture_large;mask_slot_texture_small;mask_slot_texture_large;mask_shadow_texture_small;mask_shadow_texture_large;SamplerLUT1;SamplerLUT2" mask_grille_texture_small = "../crt/shaders/crt-royale/TileableLinearApertureGrille15Wide8And5d5SpacingResizeTo64.png" mask_grille_texture_large = "../crt/shaders/crt-royale/TileableLinearApertureGrille15Wide8And5d5Spacing.png" mask_slot_texture_small = "../crt/shaders/crt-royale/TileableLinearSlotMaskTall15Wide9And4d5Horizontal9d14VerticalSpacingResizeTo64.png" @@ -47,12 +47,14 @@ mask_slot_texture_small_mipmap = "false" # Mipmapping causes artifacts with m mask_slot_texture_large_mipmap = "true" # Essential for hardware-resized masks mask_shadow_texture_small_mipmap = "false" # Mipmapping causes artifacts with manually resized masks without tex2Dlod mask_shadow_texture_large_mipmap = "true" # Essential for hardware-resized masks -SamplerLUT = "../reshade/shaders/LUT/Kurozumi_64_D65_Rec601.png" -SamplerLUT_linear = true +SamplerLUT1 = "../reshade/shaders/LUT/Kurozumi_64_D65_Rec601.png" +SamplerLUT1_linear = true +SamplerLUT2 = "../reshade/shaders/LUT/Kurozumi_64_D93_Rec601.png" +SamplerLUT2_linear = true # Pass0: LUT to correct screen colors. # Digital Displays different color coordinates for primaries than CRTs (Rec709 vs Rec601). -shader0 = "../reshade/shaders/LUT/LUT.slang" +shader0 = "../reshade/shaders/LUT/multiLUT.slang" # Pass1: Linearize the input based on CRT gamma and bob interlaced fields. # (Bobbing ensures we can immediately blur without getting artifacts.) @@ -209,7 +211,7 @@ scale_type12 = "viewport" mipmap_input12 = "true" texture_wrap_mode12 = "clamp_to_edge" -parameters = "crt_gamma;lcd_gamma;levels_contrast;halation_weight;diffusion_weight;bloom_underestimate_levels;bloom_excess;beam_min_sigma;beam_max_sigma;beam_spot_power;beam_min_shape;beam_max_shape;beam_shape_power;beam_horiz_filter;beam_horiz_sigma;beam_horiz_linear_rgb_weight;convergence_offset_x_r;convergence_offset_x_g;convergence_offset_x_b;convergence_offset_y_r;convergence_offset_y_g;convergence_offset_y_b;mask_type;mask_sample_mode_desired;mask_specify_num_triads;mask_triad_size_desired;mask_num_triads_desired;aa_subpixel_r_offset_x_runtime;aa_subpixel_r_offset_y_runtime;aa_cubic_c;aa_gauss_sigma;geom_mode_runtime;geom_radius;geom_view_dist;geom_tilt_angle_x;geom_tilt_angle_y;geom_aspect_ratio_x;geom_aspect_ratio_y;geom_overscan_x;geom_overscan_y;border_size;border_darkness;border_compress;interlace_bff;interlace_1080i;LUT_Size" +parameters = "crt_gamma;lcd_gamma;levels_contrast;halation_weight;diffusion_weight;bloom_underestimate_levels;bloom_excess;beam_min_sigma;beam_max_sigma;beam_spot_power;beam_min_shape;beam_max_shape;beam_shape_power;beam_horiz_filter;beam_horiz_sigma;beam_horiz_linear_rgb_weight;convergence_offset_x_r;convergence_offset_x_g;convergence_offset_x_b;convergence_offset_y_r;convergence_offset_y_g;convergence_offset_y_b;mask_type;mask_sample_mode_desired;mask_specify_num_triads;mask_triad_size_desired;mask_num_triads_desired;aa_subpixel_r_offset_x_runtime;aa_subpixel_r_offset_y_runtime;aa_cubic_c;aa_gauss_sigma;geom_mode_runtime;geom_radius;geom_view_dist;geom_tilt_angle_x;geom_tilt_angle_y;geom_aspect_ratio_x;geom_aspect_ratio_y;geom_overscan_x;geom_overscan_y;border_size;border_darkness;border_compress;interlace_bff;interlace_1080i" crt_gamma = "2.400000" lcd_gamma = "2.400000" levels_contrast = "0.740000" @@ -255,4 +257,3 @@ border_darkness = "0.000000" border_compress = "2.500000" interlace_bff = "0.000000" interlace_1080i = "0.000000" -LUT_Size = "64.0" diff --git a/reshade/shaders/LUT/Kurozumi_64_D93_Rec601.png b/reshade/shaders/LUT/Kurozumi_64_D93_Rec601.png new file mode 100644 index 0000000..4801db9 Binary files /dev/null and b/reshade/shaders/LUT/Kurozumi_64_D93_Rec601.png differ diff --git a/reshade/shaders/LUT/multiLUT.slang b/reshade/shaders/LUT/multiLUT.slang new file mode 100755 index 0000000..44ef9de --- /dev/null +++ b/reshade/shaders/LUT/multiLUT.slang @@ -0,0 +1,80 @@ +#version 450 + +// A version of the LUT shader that loads 2 LUTs. +// For use with Kurozumi's 64-bit colorspace LUTs. + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float LUT_selector_param; +} params; + +#pragma parameter LUT_selector_param "Color Temp (1=D65, 2=D93)" 1.0 1.0 2.0 1.0 +//#pragma parameter LUT_Size1 "LUT Size 1" 16.0 1.0 64.0 1.0 +//#pragma parameter LUT_Size2 "LUT Size 2" 16.0 1.0 64.0 1.0 +const float LUT_Size1 = 64.0; +const float LUT_Size2 = 64.0; // hardcode these for Kurozumi's LUTs + +int LUT_selector = int(params.LUT_selector_param); + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord * 1.0001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D SamplerLUT1; +layout(set = 0, binding = 4) uniform sampler2D SamplerLUT2; + +// This shouldn't be necessary but it seems some undefined values can +// creep in and each GPU vendor handles that differently. This keeps +// all values within a safe range +vec4 mixfix(vec4 a, vec4 b, float c) +{ + return (a.z < 1.0) ? mix(a, b, c) : a; +} + +void main() +{ + vec4 imgColor = texture(Source, vTexCoord.xy); + vec4 color1, color2 = vec4(0.,0.,0.,0.); + float red, green, blue1, blue2, mixer = 0.0; + if(LUT_selector == 1) + { + red = ( imgColor.r * (LUT_Size1 - 1.0) + 0.4999 ) / (LUT_Size1 * LUT_Size1); + green = ( imgColor.g * (LUT_Size1 - 1.0) + 0.4999 ) / LUT_Size1; + blue1 = (floor( imgColor.b * (LUT_Size1 - 1.0) ) / LUT_Size1) + red; + blue2 = (ceil( imgColor.b * (LUT_Size1 - 1.0) ) / LUT_Size1) + red; + mixer = clamp(max((imgColor.b - blue1) / (blue2 - blue1), 0.0), 0.0, 32.0); + color1 = texture( SamplerLUT1, vec2( blue1, green )); + color2 = texture( SamplerLUT1, vec2( blue2, green )); + } + if(LUT_selector == 2) + { + red = ( imgColor.r * (LUT_Size2 - 1.0) + 0.4999 ) / (LUT_Size2 * LUT_Size2); + green = ( imgColor.g * (LUT_Size2 - 1.0) + 0.4999 ) / LUT_Size2; + blue1 = (floor( imgColor.b * (LUT_Size2 - 1.0) ) / LUT_Size2) + red; + blue2 = (ceil( imgColor.b * (LUT_Size2 - 1.0) ) / LUT_Size2) + red; + mixer = clamp(max((imgColor.b - blue1) / (blue2 - blue1), 0.0), 0.0, 32.0); + color1 = texture( SamplerLUT2, vec2( blue1, green )); + color2 = texture( SamplerLUT2, vec2( blue2, green )); + } + FragColor = mixfix(color1, color2, mixer); +}