From df9b4808058fc8ed49b8236d278b0dadcbd51aa9 Mon Sep 17 00:00:00 2001 From: hunterk Date: Sun, 16 Feb 2020 23:11:31 -0600 Subject: [PATCH] add ntsc-adaptive, move some presets to it and remove redundant presets --- crt/crt-royale-ntsc-320px-composite.slangp | 224 ------------------ crt/crt-royale-ntsc-320px-svideo.slangp | 224 ------------------ ...langp => crt-royale-ntsc-composite.slangp} | 4 +- ...o.slangp => crt-royale-ntsc-svideo.slangp} | 7 +- ...phase.slangp => crtglow_gauss_ntsc.slangp} | 0 ntsc/ntsc-adaptive.slangp | 14 ++ ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang | 90 +++++++ ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang | 221 +++++++++++++++++ ...guest-dr-venom-ntsc-composite-256px.slangp | 4 +- ...guest-dr-venom-ntsc-composite-stock.slangp | 4 +- .../crt-guest-dr-venom-ntsc-composite.slangp | 4 +- 11 files changed, 338 insertions(+), 458 deletions(-) delete mode 100644 crt/crt-royale-ntsc-320px-composite.slangp delete mode 100644 crt/crt-royale-ntsc-320px-svideo.slangp rename crt/{crt-royale-ntsc-256px-composite.slangp => crt-royale-ntsc-composite.slangp} (98%) rename crt/{crt-royale-ntsc-256px-svideo.slangp => crt-royale-ntsc-svideo.slangp} (98%) rename crt/{crtglow_gauss_ntsc_3phase.slangp => crtglow_gauss_ntsc.slangp} (100%) create mode 100644 ntsc/ntsc-adaptive.slangp create mode 100644 ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang create mode 100644 ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang diff --git a/crt/crt-royale-ntsc-320px-composite.slangp b/crt/crt-royale-ntsc-320px-composite.slangp deleted file mode 100644 index fa2fb02..0000000 --- a/crt/crt-royale-ntsc-320px-composite.slangp +++ /dev/null @@ -1,224 +0,0 @@ -# IMPORTANT: -# Shader passes need to know details about the image in the mask_texture LUT -# files, so set the following constants in user-cgp-constants.h accordingly: -# 1.) mask_triads_per_tile = (number of horizontal triads in mask texture LUT's) -# 2.) mask_texture_small_size = (texture size of mask*texture_small LUT's) -# 3.) mask_texture_large_size = (texture size of mask*texture_large LUT's) -# 4.) mask_grille_avg_color = (avg. brightness of mask_grille_texture* LUT's, in [0, 1]) -# 5.) mask_slot_avg_color = (avg. brightness of mask_slot_texture* LUT's, in [0, 1]) -# 6.) mask_shadow_avg_color = (avg. brightness of mask_shadow_texture* LUT's, in [0, 1]) -# Shader passes also need to know certain scales set in this .slangp, but their -# compilation model doesn't currently allow the .slangp file to tell them. Make -# sure to set the following constants in user-cgp-constants.h accordingly too: -# 1.) bloom_approx_scale_x = scale_x2 -# 2.) mask_resize_viewport_scale = float2(scale_x6, scale_y5) -# Finally, shader passes need to know the value of geom_max_aspect_ratio used to -# calculate scale_y5 (among other values): -# 1.) geom_max_aspect_ratio = (geom_max_aspect_ratio used to calculate scale_y5) - -shaders = "14" - -# NTSC Shader Passes -shader0 = "../ntsc/shaders/ntsc-pass1-composite-2phase.slang" -shader1 = "../ntsc/shaders/ntsc-pass2-2phase.slang" - -filter_linear0 = false -filter_linear1 = false - -scale_type_x0 = absolute -scale_type_y0 = source -scale_x0 = 1280 -scale_y0 = 1.0 -frame_count_mod0 = 2 -float_framebuffer0 = true - -scale_type1 = source -scale_x1 = 0.5 -scale_y1 = 1.0 - -# Set an identifier, filename, and sampling traits for the phosphor mask texture. -# 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" -mask_grille_texture_small = "shaders/crt-royale/TileableLinearApertureGrille15Wide8And5d5SpacingResizeTo64.png" -mask_grille_texture_large = "shaders/crt-royale/TileableLinearApertureGrille15Wide8And5d5Spacing.png" -mask_slot_texture_small = "shaders/crt-royale/TileableLinearSlotMaskTall15Wide9And4d5Horizontal9d14VerticalSpacingResizeTo64.png" -mask_slot_texture_large = "shaders/crt-royale/TileableLinearSlotMaskTall15Wide9And4d5Horizontal9d14VerticalSpacing.png" -mask_shadow_texture_small = "shaders/crt-royale/TileableLinearShadowMaskEDPResizeTo64.png" -mask_shadow_texture_large = "shaders/crt-royale/TileableLinearShadowMaskEDP.png" -mask_grille_texture_small_wrap_mode = "repeat" -mask_grille_texture_large_wrap_mode = "repeat" -mask_slot_texture_small_wrap_mode = "repeat" -mask_slot_texture_large_wrap_mode = "repeat" -mask_shadow_texture_small_wrap_mode = "repeat" -mask_shadow_texture_large_wrap_mode = "repeat" -mask_grille_texture_small_linear = "true" -mask_grille_texture_large_linear = "true" -mask_slot_texture_small_linear = "true" -mask_slot_texture_large_linear = "true" -mask_shadow_texture_small_linear = "true" -mask_shadow_texture_large_linear = "true" -mask_grille_texture_small_mipmap = "false" # Mipmapping causes artifacts with manually resized masks without tex2Dlod -mask_grille_texture_large_mipmap = "true" # Essential for hardware-resized masks -mask_slot_texture_small_mipmap = "false" # Mipmapping causes artifacts with manually resized masks without tex2Dlod -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 - - -# Pass2: Linearize the input based on CRT gamma and bob interlaced fields. -# (Bobbing ensures we can immediately blur without getting artifacts.) -shader2 = "shaders/crt-royale/src/crt-royale-first-pass-linearize-crt-gamma-bob-fields.slang" -alias2 = "ORIG_LINEARIZED" -filter_linear2 = "false" -scale_type2 = "source" -scale2 = "1.0" -srgb_framebuffer2 = "true" - -# Pass3: Resample interlaced (and misconverged) scanlines vertically. -# Separating vertical/horizontal scanline sampling is faster: It lets us -# consider more scanlines while calculating weights for fewer pixels, and -# it reduces our samples from vertical*horizontal to vertical+horizontal. -# This has to come right after ORIG_LINEARIZED, because there's no -# "original_source" scale_type we can use later. -shader3 = "shaders/crt-royale/src/crt-royale-scanlines-vertical-interlacing.slang" -alias3 = "VERTICAL_SCANLINES" -filter_linear3 = "true" -scale_type_x3 = "source" -scale_x3 = "1.0" -scale_type_y3 = "viewport" -scale_y3 = "1.0" -#float_framebuffer3 = "true" -srgb_framebuffer3 = "true" - -# Pass4: Do a small resize blur of ORIG_LINEARIZED at an absolute size, and -# account for convergence offsets. We want to blur a predictable portion of the -# screen to match the phosphor bloom, and absolute scale works best for -# reliable results with a fixed-size bloom. Picking a scale is tricky: -# a.) 400x300 is a good compromise for the "fake-bloom" version: It's low enough -# to blur high-res/interlaced sources but high enough that resampling -# doesn't smear low-res sources too much. -# b.) 320x240 works well for the "real bloom" version: It's 1-1.5% faster, and -# the only noticeable visual difference is a larger halation spread (which -# may be a good thing for people who like to crank it up). -# Note the 4:3 aspect ratio assumes the input has cropped geom_overscan (so it's -# *intended* for an ~4:3 aspect ratio). -shader4 = "shaders/crt-royale/src/crt-royale-bloom-approx.slang" -alias4 = "BLOOM_APPROX" -filter_linear4 = "true" -scale_type4 = "absolute" -scale_x4 = "320" -scale_y4 = "240" -srgb_framebuffer4 = "true" - -# Pass5: Vertically blur the input for halation and refractive diffusion. -# Base this on BLOOM_APPROX: This blur should be small and fast, and blurring -# a constant portion of the screen is probably physically correct if the -# viewport resolution is proportional to the simulated CRT size. -shader5 = "../blurs/blur9fast-vertical.slang" -filter_linear5 = "true" -scale_type5 = "source" -scale5 = "1.0" -srgb_framebuffer5 = "true" - -# Pass6: Horizontally blur the input for halation and refractive diffusion. -# Note: Using a one-pass 9x9 blur is about 1% slower. -shader6 = "../blurs/blur9fast-horizontal.slang" -alias6 = "HALATION_BLUR" -filter_linear6 = "true" -scale_type6 = "source" -scale6 = "1.0" -srgb_framebuffer6 = "true" - -# Pass7: Lanczos-resize the phosphor mask vertically. Set the absolute -# scale_x7 == mask_texture_small_size.x (see IMPORTANT above). Larger scales -# will blur, and smaller scales could get nasty. The vertical size must be -# based on the viewport size and calculated carefully to avoid artifacts later. -# First calculate the minimum number of mask tiles we need to draw. -# Since curvature is computed after the scanline masking pass: -# num_resized_mask_tiles = 2.0; -# If curvature were computed in the scanline masking pass (it's not): -# max_mask_texel_border = ~3.0 * (1/3.0 + 4.0*sqrt(2.0) + 0.5 + 1.0); -# max_mask_tile_border = max_mask_texel_border/ -# (min_resized_phosphor_triad_size * mask_triads_per_tile); -# num_resized_mask_tiles = max(2.0, 1.0 + max_mask_tile_border * 2.0); -# At typical values (triad_size >= 2.0, mask_triads_per_tile == 8): -# num_resized_mask_tiles = ~3.8 -# Triad sizes are given in horizontal terms, so we need geom_max_aspect_ratio -# to relate them to vertical resolution. The widest we expect is: -# geom_max_aspect_ratio = 4.0/3.0 # Note: Shader passes need to know this! -# The fewer triads we tile across the screen, the larger each triad will be as a -# fraction of the viewport size, and the larger scale_y5 must be to draw a full -# num_resized_mask_tiles. Therefore, we must decide the smallest number of -# triads we'll guarantee can be displayed on screen. We'll set this according -# to 3-pixel triads at 768p resolution (the lowest anyone's likely to use): -# min_allowed_viewport_triads = 768.0*geom_max_aspect_ratio / 3.0 = 341.333333 -# Now calculate the viewport scale that ensures we can draw resized_mask_tiles: -# min_scale_x = resized_mask_tiles * mask_triads_per_tile / -# min_allowed_viewport_triads -# scale_y7 = geom_max_aspect_ratio * min_scale_x -# # Some code might depend on equal scales: -# scale_x8 = scale_y7 -# Given our default geom_max_aspect_ratio and min_allowed_viewport_triads: -# scale_y7 = 4.0/3.0 * 2.0/(341.33333 / 8.0) = 0.0625 -# IMPORTANT: The scales MUST be calculated in this way. If you wish to change -# geom_max_aspect_ratio, update that constant in user-cgp-constants.h! -shader7 = "shaders/crt-royale/src/crt-royale-mask-resize-vertical.slang" -filter_linear7 = "true" -scale_type_x7 = "absolute" -scale_x7 = "64" -scale_type_y7 = "viewport" -scale_y7 = "0.0625" # Safe for >= 341.333 horizontal triads at viewport size -#srgb_framebuffer7 = "false" # mask_texture is already assumed linear - -# Pass8: Lanczos-resize the phosphor mask horizontally. scale_x8 = scale_y7. -# TODO: Check again if the shaders actually require equal scales. -shader8 = "shaders/crt-royale/src/crt-royale-mask-resize-horizontal.slang" -alias8 = "MASK_RESIZE" -filter_linear8 = "false" -scale_type_x8 = "viewport" -scale_x8 = "0.0625" -scale_type_y8 = "source" -scale_y8 = "1.0" -#srgb_framebuffer8 = "false" # mask_texture is already assumed linear - -# Pass9: Resample (misconverged) scanlines horizontally, apply halation, and -# apply the phosphor mask. -shader9 = "shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang" -alias9 = "MASKED_SCANLINES" -filter_linear9 = "true" # This could just as easily be nearest neighbor. -scale_type9 = "viewport" -scale9 = "1.0" -#float_framebuffer9 = "true" -srgb_framebuffer9 = "true" - -# Pass 10: Compute a brightpass. This will require reading the final mask. -shader10 = "shaders/crt-royale/src/crt-royale-brightpass.slang" -alias10 = "BRIGHTPASS" -filter_linear10 = "true" # This could just as easily be nearest neighbor. -scale_type10 = "viewport" -scale10 = "1.0" -srgb_framebuffer10 = "true" - -# Pass 11: Blur the brightpass vertically -shader11 = "shaders/crt-royale/src/crt-royale-bloom-vertical.slang" -filter_linear11 = "true" # This could just as easily be nearest neighbor. -scale_type11 = "source" -scale11 = "1.0" -srgb_framebuffer11 = "true" - -# Pass 12: Blur the brightpass horizontally and combine it with the dimpass: -shader12 = "shaders/crt-royale/src/crt-royale-bloom-horizontal-reconstitute.slang" -filter_linear12 = "true" -scale_type12 = "source" -scale12 = "1.0" -srgb_framebuffer12 = "true" - -# Pass 13: Compute curvature/AA: -shader13 = "shaders/crt-royale/src/crt-royale-geometry-aa-last-pass.slang" -filter_linear13 = "true" -scale_type13 = "viewport" -mipmap_input13 = "true" -texture_wrap_mode13 = "clamp_to_edge" - diff --git a/crt/crt-royale-ntsc-320px-svideo.slangp b/crt/crt-royale-ntsc-320px-svideo.slangp deleted file mode 100644 index c7b3ae1..0000000 --- a/crt/crt-royale-ntsc-320px-svideo.slangp +++ /dev/null @@ -1,224 +0,0 @@ -# IMPORTANT: -# Shader passes need to know details about the image in the mask_texture LUT -# files, so set the following constants in user-cgp-constants.h accordingly: -# 1.) mask_triads_per_tile = (number of horizontal triads in mask texture LUT's) -# 2.) mask_texture_small_size = (texture size of mask*texture_small LUT's) -# 3.) mask_texture_large_size = (texture size of mask*texture_large LUT's) -# 4.) mask_grille_avg_color = (avg. brightness of mask_grille_texture* LUT's, in [0, 1]) -# 5.) mask_slot_avg_color = (avg. brightness of mask_slot_texture* LUT's, in [0, 1]) -# 6.) mask_shadow_avg_color = (avg. brightness of mask_shadow_texture* LUT's, in [0, 1]) -# Shader passes also need to know certain scales set in this .slangp, but their -# compilation model doesn't currently allow the .slangp file to tell them. Make -# sure to set the following constants in user-cgp-constants.h accordingly too: -# 1.) bloom_approx_scale_x = scale_x2 -# 2.) mask_resize_viewport_scale = float2(scale_x6, scale_y5) -# Finally, shader passes need to know the value of geom_max_aspect_ratio used to -# calculate scale_y5 (among other values): -# 1.) geom_max_aspect_ratio = (geom_max_aspect_ratio used to calculate scale_y5) - -shaders = "14" - -# NTSC Shader Passes -shader0 = "../ntsc/shaders/ntsc-pass1-svideo-2phase.slang" -shader1 = "../ntsc/shaders/ntsc-pass2-2phase.slang" - -filter_linear0 = false -filter_linear1 = false - -scale_type_x0 = absolute -scale_type_y0 = source -scale_x0 = 1920 -scale_y0 = 1.0 -frame_count_mod0 = 2 -float_framebuffer0 = true - -scale_type1 = source -scale_x1 = 0.5 -scale_y1 = 1.0 - -# Set an identifier, filename, and sampling traits for the phosphor mask texture. -# 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" -mask_grille_texture_small = "shaders/crt-royale/TileableLinearApertureGrille15Wide8And5d5SpacingResizeTo64.png" -mask_grille_texture_large = "shaders/crt-royale/TileableLinearApertureGrille15Wide8And5d5Spacing.png" -mask_slot_texture_small = "shaders/crt-royale/TileableLinearSlotMaskTall15Wide9And4d5Horizontal9d14VerticalSpacingResizeTo64.png" -mask_slot_texture_large = "shaders/crt-royale/TileableLinearSlotMaskTall15Wide9And4d5Horizontal9d14VerticalSpacing.png" -mask_shadow_texture_small = "shaders/crt-royale/TileableLinearShadowMaskEDPResizeTo64.png" -mask_shadow_texture_large = "shaders/crt-royale/TileableLinearShadowMaskEDP.png" -mask_grille_texture_small_wrap_mode = "repeat" -mask_grille_texture_large_wrap_mode = "repeat" -mask_slot_texture_small_wrap_mode = "repeat" -mask_slot_texture_large_wrap_mode = "repeat" -mask_shadow_texture_small_wrap_mode = "repeat" -mask_shadow_texture_large_wrap_mode = "repeat" -mask_grille_texture_small_linear = "true" -mask_grille_texture_large_linear = "true" -mask_slot_texture_small_linear = "true" -mask_slot_texture_large_linear = "true" -mask_shadow_texture_small_linear = "true" -mask_shadow_texture_large_linear = "true" -mask_grille_texture_small_mipmap = "false" # Mipmapping causes artifacts with manually resized masks without tex2Dlod -mask_grille_texture_large_mipmap = "true" # Essential for hardware-resized masks -mask_slot_texture_small_mipmap = "false" # Mipmapping causes artifacts with manually resized masks without tex2Dlod -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 - - -# Pass2: Linearize the input based on CRT gamma and bob interlaced fields. -# (Bobbing ensures we can immediately blur without getting artifacts.) -shader2 = "shaders/crt-royale/src/crt-royale-first-pass-linearize-crt-gamma-bob-fields.slang" -alias2 = "ORIG_LINEARIZED" -filter_linear2 = "false" -scale_type2 = "source" -scale2 = "1.0" -srgb_framebuffer2 = "true" - -# Pass3: Resample interlaced (and misconverged) scanlines vertically. -# Separating vertical/horizontal scanline sampling is faster: It lets us -# consider more scanlines while calculating weights for fewer pixels, and -# it reduces our samples from vertical*horizontal to vertical+horizontal. -# This has to come right after ORIG_LINEARIZED, because there's no -# "original_source" scale_type we can use later. -shader3 = "shaders/crt-royale/src/crt-royale-scanlines-vertical-interlacing.slang" -alias3 = "VERTICAL_SCANLINES" -filter_linear3 = "true" -scale_type_x3 = "source" -scale_x3 = "1.0" -scale_type_y3 = "viewport" -scale_y3 = "1.0" -#float_framebuffer3 = "true" -srgb_framebuffer3 = "true" - -# Pass4: Do a small resize blur of ORIG_LINEARIZED at an absolute size, and -# account for convergence offsets. We want to blur a predictable portion of the -# screen to match the phosphor bloom, and absolute scale works best for -# reliable results with a fixed-size bloom. Picking a scale is tricky: -# a.) 400x300 is a good compromise for the "fake-bloom" version: It's low enough -# to blur high-res/interlaced sources but high enough that resampling -# doesn't smear low-res sources too much. -# b.) 320x240 works well for the "real bloom" version: It's 1-1.5% faster, and -# the only noticeable visual difference is a larger halation spread (which -# may be a good thing for people who like to crank it up). -# Note the 4:3 aspect ratio assumes the input has cropped geom_overscan (so it's -# *intended* for an ~4:3 aspect ratio). -shader4 = "shaders/crt-royale/src/crt-royale-bloom-approx.slang" -alias4 = "BLOOM_APPROX" -filter_linear4 = "true" -scale_type4 = "absolute" -scale_x4 = "320" -scale_y4 = "240" -srgb_framebuffer4 = "true" - -# Pass5: Vertically blur the input for halation and refractive diffusion. -# Base this on BLOOM_APPROX: This blur should be small and fast, and blurring -# a constant portion of the screen is probably physically correct if the -# viewport resolution is proportional to the simulated CRT size. -shader5 = "../blurs/blur9fast-vertical.slang" -filter_linear5 = "true" -scale_type5 = "source" -scale5 = "1.0" -srgb_framebuffer5 = "true" - -# Pass6: Horizontally blur the input for halation and refractive diffusion. -# Note: Using a one-pass 9x9 blur is about 1% slower. -shader6 = "../blurs/blur9fast-horizontal.slang" -alias6 = "HALATION_BLUR" -filter_linear6 = "true" -scale_type6 = "source" -scale6 = "1.0" -srgb_framebuffer6 = "true" - -# Pass7: Lanczos-resize the phosphor mask vertically. Set the absolute -# scale_x7 == mask_texture_small_size.x (see IMPORTANT above). Larger scales -# will blur, and smaller scales could get nasty. The vertical size must be -# based on the viewport size and calculated carefully to avoid artifacts later. -# First calculate the minimum number of mask tiles we need to draw. -# Since curvature is computed after the scanline masking pass: -# num_resized_mask_tiles = 2.0; -# If curvature were computed in the scanline masking pass (it's not): -# max_mask_texel_border = ~3.0 * (1/3.0 + 4.0*sqrt(2.0) + 0.5 + 1.0); -# max_mask_tile_border = max_mask_texel_border/ -# (min_resized_phosphor_triad_size * mask_triads_per_tile); -# num_resized_mask_tiles = max(2.0, 1.0 + max_mask_tile_border * 2.0); -# At typical values (triad_size >= 2.0, mask_triads_per_tile == 8): -# num_resized_mask_tiles = ~3.8 -# Triad sizes are given in horizontal terms, so we need geom_max_aspect_ratio -# to relate them to vertical resolution. The widest we expect is: -# geom_max_aspect_ratio = 4.0/3.0 # Note: Shader passes need to know this! -# The fewer triads we tile across the screen, the larger each triad will be as a -# fraction of the viewport size, and the larger scale_y5 must be to draw a full -# num_resized_mask_tiles. Therefore, we must decide the smallest number of -# triads we'll guarantee can be displayed on screen. We'll set this according -# to 3-pixel triads at 768p resolution (the lowest anyone's likely to use): -# min_allowed_viewport_triads = 768.0*geom_max_aspect_ratio / 3.0 = 341.333333 -# Now calculate the viewport scale that ensures we can draw resized_mask_tiles: -# min_scale_x = resized_mask_tiles * mask_triads_per_tile / -# min_allowed_viewport_triads -# scale_y7 = geom_max_aspect_ratio * min_scale_x -# # Some code might depend on equal scales: -# scale_x8 = scale_y7 -# Given our default geom_max_aspect_ratio and min_allowed_viewport_triads: -# scale_y7 = 4.0/3.0 * 2.0/(341.33333 / 8.0) = 0.0625 -# IMPORTANT: The scales MUST be calculated in this way. If you wish to change -# geom_max_aspect_ratio, update that constant in user-cgp-constants.h! -shader7 = "shaders/crt-royale/src/crt-royale-mask-resize-vertical.slang" -filter_linear7 = "true" -scale_type_x7 = "absolute" -scale_x7 = "64" -scale_type_y7 = "viewport" -scale_y7 = "0.0625" # Safe for >= 341.333 horizontal triads at viewport size -#srgb_framebuffer7 = "false" # mask_texture is already assumed linear - -# Pass8: Lanczos-resize the phosphor mask horizontally. scale_x8 = scale_y7. -# TODO: Check again if the shaders actually require equal scales. -shader8 = "shaders/crt-royale/src/crt-royale-mask-resize-horizontal.slang" -alias8 = "MASK_RESIZE" -filter_linear8 = "false" -scale_type_x8 = "viewport" -scale_x8 = "0.0625" -scale_type_y8 = "source" -scale_y8 = "1.0" -#srgb_framebuffer8 = "false" # mask_texture is already assumed linear - -# Pass9: Resample (misconverged) scanlines horizontally, apply halation, and -# apply the phosphor mask. -shader9 = "shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang" -alias9 = "MASKED_SCANLINES" -filter_linear9 = "true" # This could just as easily be nearest neighbor. -scale_type9 = "viewport" -scale9 = "1.0" -#float_framebuffer9 = "true" -srgb_framebuffer9 = "true" - -# Pass 10: Compute a brightpass. This will require reading the final mask. -shader10 = "shaders/crt-royale/src/crt-royale-brightpass.slang" -alias10 = "BRIGHTPASS" -filter_linear10 = "true" # This could just as easily be nearest neighbor. -scale_type10 = "viewport" -scale10 = "1.0" -srgb_framebuffer10 = "true" - -# Pass 11: Blur the brightpass vertically -shader11 = "shaders/crt-royale/src/crt-royale-bloom-vertical.slang" -filter_linear11 = "true" # This could just as easily be nearest neighbor. -scale_type11 = "source" -scale11 = "1.0" -srgb_framebuffer11 = "true" - -# Pass 12: Blur the brightpass horizontally and combine it with the dimpass: -shader12 = "shaders/crt-royale/src/crt-royale-bloom-horizontal-reconstitute.slang" -filter_linear12 = "true" -scale_type12 = "source" -scale12 = "1.0" -srgb_framebuffer12 = "true" - -# Pass 13: Compute curvature/AA: -shader13 = "shaders/crt-royale/src/crt-royale-geometry-aa-last-pass.slang" -filter_linear13 = "true" -scale_type13 = "viewport" -mipmap_input13 = "true" -texture_wrap_mode13 = "clamp_to_edge" - diff --git a/crt/crt-royale-ntsc-256px-composite.slangp b/crt/crt-royale-ntsc-composite.slangp similarity index 98% rename from crt/crt-royale-ntsc-256px-composite.slangp rename to crt/crt-royale-ntsc-composite.slangp index 4f8ebf7..20fa358 100644 --- a/crt/crt-royale-ntsc-256px-composite.slangp +++ b/crt/crt-royale-ntsc-composite.slangp @@ -19,8 +19,8 @@ shaders = "14" # NTSC Shader Passes -shader0 = "../ntsc/shaders/ntsc-pass1-composite-3phase.slang" -shader1 = "../ntsc/shaders/ntsc-pass2-3phase.slang" +shader0 = "../ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang" +shader1 = "../ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang" filter_linear0 = false filter_linear1 = false diff --git a/crt/crt-royale-ntsc-256px-svideo.slangp b/crt/crt-royale-ntsc-svideo.slangp similarity index 98% rename from crt/crt-royale-ntsc-256px-svideo.slangp rename to crt/crt-royale-ntsc-svideo.slangp index 51678d8..175eb8c 100644 --- a/crt/crt-royale-ntsc-256px-svideo.slangp +++ b/crt/crt-royale-ntsc-svideo.slangp @@ -19,8 +19,8 @@ shaders = "14" # NTSC Shader Passes -shader0 = "../ntsc/shaders/ntsc-pass1-svideo-3phase.slang" -shader1 = "../ntsc/shaders/ntsc-pass2-3phase.slang" +shader0 = "../ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang" +shader1 = "../ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang" filter_linear0 = false filter_linear1 = false @@ -222,3 +222,6 @@ scale_type13 = "viewport" mipmap_input13 = "true" texture_wrap_mode13 = "clamp_to_edge" +parameters = "quality" +quality = 1.0 + diff --git a/crt/crtglow_gauss_ntsc_3phase.slangp b/crt/crtglow_gauss_ntsc.slangp similarity index 100% rename from crt/crtglow_gauss_ntsc_3phase.slangp rename to crt/crtglow_gauss_ntsc.slangp diff --git a/ntsc/ntsc-adaptive.slangp b/ntsc/ntsc-adaptive.slangp new file mode 100644 index 0000000..d49e840 --- /dev/null +++ b/ntsc/ntsc-adaptive.slangp @@ -0,0 +1,14 @@ +shaders = 2 + +shader0 = shaders/ntsc-adaptive/ntsc-pass1.slang +scale_type0 = source +scale_x0 = 4.0 +filter_linear0 = false +scale_y0 = 1.0 +float_framebuffer0 = true + +shader1 = shaders/ntsc-adaptive/ntsc-pass2.slang +scale_type1 = source +scale_x1 = 0.5 +scale_y1 = 1.0 +filter_linear1 = false diff --git a/ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang b/ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang new file mode 100644 index 0000000..2b4b097 --- /dev/null +++ b/ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang @@ -0,0 +1,90 @@ +#version 450 + +// NTSC-Adaptive +// based on Themaister's NTSC shader + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; + uint FrameCount; + float quality, bw; +} global; + +#pragma parameter quality "Quality (Composite = 0, Svideo = 1)" 0.0 0.0 1.0 1.0 +#pragma parameter bw "Black and White" 0.0 0.0 1.0 1.0 + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; +layout(location = 1) out vec2 pix_no; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; + pix_no = TexCoord * global.SourceSize.xy * (global.OutputSize.xy / global.SourceSize.xy); +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec2 pix_no; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +#define PI 3.14159265 +float phase = (global.OriginalSize.x > 300.0) ? 2.0 : 3.0; +float CHROMA_MOD_FREQ = (phase < 2.5) ? (4.0 * PI / 15.0) : (PI / 3.0); +float ARTIFACTING = 1.0 - global.quality; +float FRINGING = 1.0 - global.quality; +float SATURATION = 1.0 - global.bw; +// prevent some very slight clipping that happens at 1.0 +const float BRIGHTNESS = 0.95; + +mat3 mix_mat = mat3( + BRIGHTNESS, FRINGING, FRINGING, + ARTIFACTING, 2.0 * SATURATION, 0.0, + ARTIFACTING, 0.0, 2.0 * SATURATION +); + +const mat3 yiq2rgb_mat = mat3( + 1.0, 0.956, 0.6210, + 1.0, -0.2720, -0.6474, + 1.0, -1.1060, 1.7046); + +vec3 yiq2rgb(vec3 yiq) +{ + return yiq * yiq2rgb_mat; +} + +const mat3 yiq_mat = mat3( + 0.2989, 0.5870, 0.1140, + 0.5959, -0.2744, -0.3216, + 0.2115, -0.5229, 0.3114 +); + +vec3 rgb2yiq(vec3 col) +{ + return col * yiq_mat; +} + +void main() +{ + vec3 col = texture(Source, vTexCoord).rgb; + vec3 yiq = rgb2yiq(col); + + float chroma_phase = (phase < 2.5) ? PI * (mod(pix_no.y, 2.0) + mod(global.FrameCount, 2.)) : 0.6667 * PI * (mod(pix_no.y, 3.0) + mod(global.FrameCount, 2.)); + + float mod_phase = chroma_phase + pix_no.x * CHROMA_MOD_FREQ; + + float i_mod = cos(mod_phase); + float q_mod = sin(mod_phase); + + yiq.yz *= vec2(i_mod, q_mod); // Modulate. + yiq *= mix_mat; // Cross-talk. + yiq.yz *= vec2(i_mod, q_mod); // Demodulate. + FragColor = vec4(yiq, 1.0); +} diff --git a/ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang b/ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang new file mode 100644 index 0000000..458ae3a --- /dev/null +++ b/ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang @@ -0,0 +1,221 @@ +#version 450 + +// NTSC-Adaptive +// based on Themaister's NTSC shader + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; + float linearize; +} global; + +#pragma parameter linearize "Linearize Output Gamma" 0.0 0.0 1.0 1.0 + +#define fetch_offset(offset, one_x) \ + texture(Source, vTexCoord + vec2((offset) * (one_x), 0.0)).xyz + +#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 - vec2(0.5 / global.SourceSize.x, 0.0); // Compensate for decimate-by-2. +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +float phase = (global.OriginalSize.x > 300.0) ? 2.0 : 3.0; + +const mat3 yiq2rgb_mat = mat3( + 1.0, 0.956, 0.6210, + 1.0, -0.2720, -0.6474, + 1.0, -1.1060, 1.7046); + +vec3 yiq2rgb(vec3 yiq) +{ + return yiq * yiq2rgb_mat; +} + +const mat3 yiq_mat = mat3( + 0.2989, 0.5870, 0.1140, + 0.5959, -0.2744, -0.3216, + 0.2115, -0.5229, 0.3114 +); + +vec3 rgb2yiq(vec3 col) +{ + return col * yiq_mat; +} + +const int TAPS_2_phase = 32; +const float luma_filter_2_phase[33] = float[33]( + -0.000174844, + -0.000205844, + -0.000149453, + -0.000051693, + 0.000000000, + -0.000066171, + -0.000245058, + -0.000432928, + -0.000472644, + -0.000252236, + 0.000198929, + 0.000687058, + 0.000944112, + 0.000803467, + 0.000363199, + 0.000013422, + 0.000253402, + 0.001339461, + 0.002932972, + 0.003983485, + 0.003026683, + -0.001102056, + -0.008373026, + -0.016897700, + -0.022914480, + -0.021642347, + -0.008863273, + 0.017271957, + 0.054921920, + 0.098342579, + 0.139044281, + 0.168055832, + 0.178571429); + +const float chroma_filter_2_phase[33] = float[33]( + 0.001384762, + 0.001678312, + 0.002021715, + 0.002420562, + 0.002880460, + 0.003406879, + 0.004004985, + 0.004679445, + 0.005434218, + 0.006272332, + 0.007195654, + 0.008204665, + 0.009298238, + 0.010473450, + 0.011725413, + 0.013047155, + 0.014429548, + 0.015861306, + 0.017329037, + 0.018817382, + 0.020309220, + 0.021785952, + 0.023227857, + 0.024614500, + 0.025925203, + 0.027139546, + 0.028237893, + 0.029201910, + 0.030015081, + 0.030663170, + 0.031134640, + 0.031420995, + 0.031517031); + +const int TAPS_3_phase = 24; +const float luma_filter_3_phase[25] = float[25]( + -0.000012020, + -0.000022146, + -0.000013155, + -0.000012020, + -0.000049979, + -0.000113940, + -0.000122150, + -0.000005612, + 0.000170516, + 0.000237199, + 0.000169640, + 0.000285688, + 0.000984574, + 0.002018683, + 0.002002275, + -0.000909882, + -0.007049081, + -0.013222860, + -0.012606931, + 0.002460860, + 0.035868225, + 0.084016453, + 0.135563500, + 0.175261268, + 0.190176552); + +const float chroma_filter_3_phase[25] = float[25]( + -0.000118847, + -0.000271306, + -0.000502642, + -0.000930833, + -0.001451013, + -0.002064744, + -0.002700432, + -0.003241276, + -0.003524948, + -0.003350284, + -0.002491729, + -0.000721149, + 0.002164659, + 0.006313635, + 0.011789103, + 0.018545660, + 0.026414396, + 0.035100710, + 0.044196567, + 0.053207202, + 0.061590275, + 0.068803602, + 0.074356193, + 0.077856564, + 0.079052396); + +void main() +{ + float one_x = global.SourceSize.z; + vec3 signal = vec3(0.0); + + if(phase < 2.5) + { + for (int i = 0; i < TAPS_2_phase; i++) + { + float offset = float(i); + + vec3 sums = fetch_offset(offset - float(TAPS_2_phase), one_x) + + fetch_offset(float(TAPS_2_phase) - offset, one_x); + signal += sums * vec3(luma_filter_2_phase[i], chroma_filter_2_phase[i], chroma_filter_2_phase[i]); + } + signal += texture(Source, vTexCoord).xyz * + vec3(luma_filter_2_phase[TAPS_2_phase], chroma_filter_2_phase[TAPS_2_phase], chroma_filter_2_phase[TAPS_2_phase]); + } + else if(phase > 2.5) + { + for (int i = 0; i < TAPS_3_phase; i++) + { + float offset = float(i); + + vec3 sums = fetch_offset(offset - float(TAPS_3_phase), one_x) + + fetch_offset(float(TAPS_3_phase) - offset, one_x); + signal += sums * vec3(luma_filter_3_phase[i], chroma_filter_3_phase[i], chroma_filter_3_phase[i]); + } + signal += texture(Source, vTexCoord).xyz * + vec3(luma_filter_3_phase[TAPS_3_phase], chroma_filter_3_phase[TAPS_3_phase], chroma_filter_3_phase[TAPS_3_phase]); + } + + vec3 rgb = yiq2rgb(signal); + FragColor = vec4(rgb, 1.0); + if(global.linearize < 0.5) return; + else FragColor = pow(FragColor, vec4(2.2)); +} diff --git a/presets/crt-guest-dr-venom-ntsc-composite-256px.slangp b/presets/crt-guest-dr-venom-ntsc-composite-256px.slangp index 6537bd8..c0d5f6c 100644 --- a/presets/crt-guest-dr-venom-ntsc-composite-256px.slangp +++ b/presets/crt-guest-dr-venom-ntsc-composite-256px.slangp @@ -1,7 +1,7 @@ shaders = 12 -shader0 = ../ntsc/shaders/ntsc-pass1-composite-3phase.slang -shader1 = ../ntsc/shaders/ntsc-pass2-3phase-gamma.slang +shader0 = ../ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang +shader1 = ../ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang filter_linear0 = false filter_linear1 = false diff --git a/presets/crt-guest-dr-venom-ntsc-composite-stock.slangp b/presets/crt-guest-dr-venom-ntsc-composite-stock.slangp index 6ecbad9..3946288 100644 --- a/presets/crt-guest-dr-venom-ntsc-composite-stock.slangp +++ b/presets/crt-guest-dr-venom-ntsc-composite-stock.slangp @@ -6,8 +6,8 @@ scale_type_x0 = source scale_type_y0 = absolute scale_y0 = 240 -shader1 = ../ntsc/shaders/ntsc-pass1-composite-2phase.slang -shader2 = ../ntsc/shaders/ntsc-pass2-2phase-gamma.slang +shader1 = ../ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang +shader2 = ../ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang filter_linear1 = false filter_linear2 = false diff --git a/presets/crt-guest-dr-venom-ntsc-composite.slangp b/presets/crt-guest-dr-venom-ntsc-composite.slangp index 12f3020..c0d5f6c 100644 --- a/presets/crt-guest-dr-venom-ntsc-composite.slangp +++ b/presets/crt-guest-dr-venom-ntsc-composite.slangp @@ -1,7 +1,7 @@ shaders = 12 -shader0 = ../ntsc/shaders/ntsc-pass1-composite-2phase.slang -shader1 = ../ntsc/shaders/ntsc-pass2-2phase-gamma.slang +shader0 = ../ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang +shader1 = ../ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang filter_linear0 = false filter_linear1 = false