Crt royale with ntsc?

Hi!

I was wondering if anybody knows of a way of coupling the amazing crt royale shader with an ntsc shader when playing snes games? I am on windows7 using the latest retroarch build. I have tried enabling soft filters but that doesnt seem to work. I usually use themaisters ntsc-shader with crt.geom which is great, but i would really love to try royale with ntsc too:)

You would need to merge the NTSC cgp with the crt-royale one. I suspect it would require a beefy GPU.

I’m surprised the softfilters aren’t working. They should be applicable to SNES.

Thanks for the reply! The soft filters always worked, and still work, on the stable version of retroarch, but that one is not compatible with crt royale as far as i know…? Trying to use filters on the latest build only returns a “failed to load filter” error… I have an nvidia 285 gtx card which can handle a great deal. Merging ntsc and royale might be too demanding though:) How do i combine the two? Im not that experienced with the technical aspects of shaders im afraid. I have made a couple of failed attempts to “paste” the ntsc shader into royale, but so far no luck…

d’oh, I forgot that shader passes are hard-capped at 13, so NTSC shader + royale just isn’t possible.

For the softfilters, which core are you trying to use? They work fine for me with snes9x and derivs but not with bsnes-* and it complains about the wrong pixel format. It’s doing that with an older nightly (a few weeks old), too. Did it work with bsnes previously?

It looks like the other softfilters are fine, even with bsnes, so it appears to be an issue specifically with the ntsc filters, though that’s not surprising, as they’re finicky.

Hey, Twinaphex bumped up the limit, so this is possible now. Still requires a beast of a GPU, but here you go:

# 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 .cgp, but their
# compilation model doesn't currently allow the .cgp 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 = "16"

# 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 = "TileableLinearApertureGrille15Wide8And5d5SpacingResizeTo64.png"
mask_grille_texture_large = "TileableLinearApertureGrille15Wide8And5d5Spacing.png"
mask_slot_texture_small = "TileableLinearSlotMaskTall15Wide9And4d5Horizontal9d14VerticalSpacingResizeTo64.png"
mask_slot_texture_large = "TileableLinearSlotMaskTall15Wide9And4d5Horizontal9d14VerticalSpacing.png"
mask_shadow_texture_small = "TileableLinearShadowMaskEDPResizeTo64.png"
mask_shadow_texture_large = "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

shader0 = ../ntsc/shaders/ntsc-pass1-composite-3phase.cg
shader1 = ../ntsc/shaders//ntsc-pass2-3phase.cg
shader2 = ../ntsc/shaders//ntsc-gauss-pass.cg
shader3 = ../ntsc/shaders/ntsc-stock.cg

filter_linear0 = false
filter_linear1 = false
filter_linear2 = false
filter_linear3 = true 

scale_type0 = source
scale_x0 = 4.0
scale_y0 = 1.0
frame_count_mod0 = 2
float_framebuffer0 = true

scale_type1 = source
scale_x1 = 0.5
scale_y1 = 1.0

scale_type_x2 = source
scale_type_y2 = viewport
scale2 = 1.0


# Pass4: Linearize the input based on CRT gamma and bob interlaced fields.
# (Bobbing ensures we can immediately blur without getting artifacts.)
shader4 = "shaders/crt-royale/src/crt-royale-first-pass-linearize-crt-gamma-bob-fields.cg"
alias4 = "ORIG_LINEARIZED"
filter_linear4 = "false"
scale_type4 = "source"
scale4 = "1.0"
srgb_framebuffer4 = "true"

# Pass5: 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.
shader5 = "shaders/crt-royale/src/crt-royale-scanlines-vertical-interlacing.cg"
alias5 = "VERTICAL_SCANLINES"
filter_linear5 = "true"
scale_type_x5 = "source"
scale_x5 = "1.0"
scale_type_y5 = "viewport"
scale_y5 = "1.0"
#float_framebuffer5 = "true"
srgb_framebuffer5 = "true"

# Pass6: 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).
shader6 = "shaders/crt-royale/src/crt-royale-bloom-approx.cg"
alias6 = "BLOOM_APPROX"
filter_linear6 = "true"
scale_type6 = "absolute"
scale_x6 = "320"
scale_y6 = "240"
srgb_framebuffer6 = "true"

# Pass7: 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.
shader7 = "../../blurs/blur9fast-vertical.cg"
filter_linear7 = "true"
scale_type7 = "source"
scale7 = "1.0"
srgb_framebuffer3 = "true"

# Pass8: Horizontally blur the input for halation and refractive diffusion.
# Note: Using a one-pass 9x9 blur is about 1% slower.
shader8 = "../../blurs/blur9fast-horizontal.cg"
alias8 = "HALATION_BLUR"
filter_linear8 = "true"
scale_type8 = "source"
scale8 = "1.0"
srgb_framebuffer8 = "true"

# Pass9: Lanczos-resize the phosphor mask vertically.  Set the absolute
# scale_x9 == 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_y9 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_y9 = geom_max_aspect_ratio * min_scale_x
#   # Some code might depend on equal scales:
#   scale_x10 = scale_y9
# Given our default geom_max_aspect_ratio and min_allowed_viewport_triads:
#   scale_y9 = 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!
shader9 = "shaders/crt-royale/src/crt-royale-mask-resize-vertical.cg"
filter_linear9 = "true"
scale_type_x9 = "absolute"
scale_x9 = "64"
scale_type_y9 = "viewport"
scale_y9 = "0.0625" # Safe for >= 341.333 horizontal triads at viewport size
#srgb_framebuffer9 = "false" # mask_texture is already assumed linear

# Pass10: Lanczos-resize the phosphor mask horizontally.  scale_x10 = scale_y5.
# TODO: Check again if the shaders actually require equal scales.
shader10 = "shaders/crt-royale/src/crt-royale-mask-resize-horizontal.cg"
alias10 = "MASK_RESIZE"
filter_linear10 = "false"
scale_type_x10 = "viewport"
scale_x10 = "0.0625"
scale_type_y10 = "source"
scale_y10 = "1.0"
#srgb_framebuffer10 = "false" # mask_texture is already assumed linear

# Pass11: Resample (misconverged) scanlines horizontally, apply halation, and
# apply the phosphor mask.
shader11 = "shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.cg"
alias11 = "MASKED_SCANLINES"
filter_linear11 = "true" # This could just as easily be nearest neighbor.
scale_type11 = "viewport"
scale11 = "1.0"
#float_framebuffer11 = "true"
srgb_framebuffer11 = "true"

# Pass 12: Compute a brightpass.  This will require reading the final mask.
shader12 = "shaders/crt-royale/src/crt-royale-brightpass.cg"
alias12 = "BRIGHTPASS"
filter_linear12 = "true" # This could just as easily be nearest neighbor.
scale_type12 = "viewport"
scale12 = "1.0"
srgb_framebuffer12 = "true"

# Pass 13: Blur the brightpass vertically
shader13 = "shaders/crt-royale/src/crt-royale-bloom-vertical.cg"
filter_linear13 = "true" # This could just as easily be nearest neighbor.
scale_type13 = "source"
scale13 = "1.0"
srgb_framebuffer13 = "true"

# Pass 14: Blur the brightpass horizontally and combine it with the dimpass:
shader14 = "shaders/crt-royale/src/crt-royale-bloom-horizontal-reconstitute.cg"
filter_linear14 = "true"
scale_type14 = "source"
scale14 = "1.0"
srgb_framebuffer14 = "true"

# Pass 15: Compute curvature/AA:
shader15 = "shaders/crt-royale/src/crt-royale-geometry-aa-last-pass.cg"
filter_linear15 = "true"
scale_type15 = "viewport"
mipmap_input15 = "true"
texture_wrap_mode15 = "clamp_to_edge"


1 Like

Wow! Thank you so much! That is awesome! Sorry for the late reply, ive been a bit busy lately, but i really appreciate your response and the great efforts of the dedicated community! Even if my pc cant handle it, its always cool to see limits being pushed;) Great work by Twinaphex! Cant wait to try it out!

I’m having a hard time getting it working on my machine, not sure if my folder directories are incorrect or the .cg files are wrong or what, does anyone have a zip with all the .cg’s and in their correct place?

Yeah, there was a big shuffle in all of the common-shaders files. I updated the post above to match the new layout (hopefully). Give it a shot :slight_smile: