Crt-Royale Kurozumi Edition Help

Hello, I found these wonderful settings for crt-royale that really give it an awesome vibe. It creates more of the RGB BVM style monitor look.

They really take crt-royale in a different direction giving it the higher end RGB BVM style. All shots are integer scaling on.

Thanks to Kurozumi for posting the settings. Thanks TroggleMonkey for his amazing work on this shader.

Make sure to click to view in full size. They are sharp, and crisp.

levels_contrast = β€œ0.750000” <-- tweak this setting to adjust overall brightness. From β€œ0.950000” down to β€œ0.500000”

mask_type = β€œ0.000000” <-- If things look strange for some reason, try changing this to mask_type = β€œ2.000000”

mask_num_triads_desired = β€œ800.000000” <β€” Tweaks the scan lines. Good values are 800,900,1000.

Load up crt-royale and then save it as a cgp. Then add this towards the bottom replacing the other settings.

crt_gamma = β€œ2.500000” lcd_gamma = β€œ2.200000” levels_contrast = β€œ0.750000” halation_weight = β€œ0.000000” diffusion_weight = β€œ0.010000” bloom_underestimate_levels = β€œ0.800000” bloom_excess = β€œ0.000000” beam_min_sigma = β€œ0.015000” beam_max_sigma = β€œ0.200000” beam_spot_power = β€œ0.330000” beam_min_shape = β€œ2.000000” beam_max_shape = β€œ4.000000” beam_shape_power = β€œ0.250000” beam_horiz_filter = β€œ0.000000” beam_horiz_sigma = β€œ0.545000” beam_horiz_linear_rgb_weight = β€œ1.000000” convergence_offset_x_r = β€œ0.000000” convergence_offset_x_g = β€œ0.000000” convergence_offset_x_b = β€œ0.000000” convergence_offset_y_r = β€œ0.100000” convergence_offset_y_g = β€œ-0.100000” convergence_offset_y_b = β€œ0.100000” mask_type = β€œ0.000000” mask_sample_mode_desired = β€œ0.000000” mask_specify_num_triads = β€œ1.000000” mask_triad_size_desired = β€œ3.000000” mask_num_triads_desired = β€œ800.000000” aa_subpixel_r_offset_x_runtime = β€œ-0.333333” aa_subpixel_r_offset_y_runtime = β€œ0.000000” aa_cubic_c = β€œ0.500000” aa_gauss_sigma = β€œ0.500000” geom_mode_runtime = β€œ0.000000” geom_radius = β€œ2.000000” geom_view_dist = β€œ2.000000” geom_tilt_angle_x = β€œ0.000000” geom_tilt_angle_y = β€œ0.000000” geom_aspect_ratio_x = β€œ432.000000” geom_aspect_ratio_y = β€œ329.000000” geom_overscan_x = β€œ1.000000” geom_overscan_y = β€œ1.000000” border_size = β€œ0.005000” border_darkness = β€œ0.000000” border_compress = β€œ2.500000” interlace_bff = β€œ0.000000” interlace_1080i = β€œ0.000000”

1 Like

Here is an example of a real BVM to compare.

Here are a few more. This shader is really blowing my mind right now. It’s like an eyegasm. Everything looks so rich andd lush. I guess im the only one? :slight_smile:

Integer scaling on.

Make sure to click the link twice so it’s the β€œ/full/” version in the link or else the scanlines look off.

Those settings look pretty great. Sadly, none of my GPUs can run it full speed.

Thanks hunterk. Yeah they definitely take some GPU power to run. My card is a GTX 860M. Maybe try with the crt-royale-intel base?

Here are two comparison shots between the shader screenshot, and camera photos of a real S-Video SD TV, and a real PVM/BVM monitor. The full screenshot and the camera BVM photos are scary close when you zoom in.

I almost cant believe it, as PVM/BVM monitors are considered by some the best in show for retro gaming.

Click the picture twice to zoom in all the way to the /full/ size link.

First round of donations. Hunterk needs a new GPU! :slight_smile:

Hi,

I would like to try this new shader, but one question :

Is it very important to set integrer scale on ? What if I try this shader with exactly the same settings except for integrer scale off ? Will I lose something in quality ?

Thanks

[QUOTE=hostile1975;33230]Hi,

I would like to try this new shader, but one question :

Is it very important to set integrer scale on ? What if I try this shader with exactly the same settings except for integrer scale off ? Will I lose something in quality ?

Thanks[/QUOTE]

Without it you will have uneven scan lines and destroy the look.

I like to set integer scaling on, then set a custom ratio(a few options above) to like 5x5 or what ever works for your display/resolution, so there is no black space above the image, only on the sides. Just use the d-pad or arrow keys to set the custom ratio until the top black is gone. This basically creates a 4:3 image on my 1080p display.

Personally, I don’t really see anything special about the shots. All I see are shots with perhaps a bit too much saturation, far too strong thick scanlines, and perfect geometry - did the BVMs have perfect flat, non-curved, geometry ? I still prefer crt-easymode-halation, with a small bit of curve because every single TV and monitor I owned since the 80s had a slight curve. Still, everyone’s taste is different and I respect the op’s results.

1 Like

[QUOTE=John.Merrit;33237]Personally, I don’t really see anything special about the shots. All I see are shots with perhaps a bit too much saturation, far too strong thick scanlines, and perfect geometry - did the BVMs have perfect flat, non-curved, geometry ? I still prefer crt-easymode-halation, with a small bit of curve because every single TV and monitor I owned since the 80s had a slight curve. Still, everyone’s taste is different and I respect the op’s results.[/QUOTE]

John, my original intention of this thread was to ask users to help make it even better. As I still dont fully understand all of the options.

levels_contrast will change the saturation levels. I like 50 or 75.

Everyone has different tastes. I just had not seen any shader do what this does yet. There are also options to add geometry towards the bottom. I personally dont like geom on my flat screens. I love scanlines, and this does them in an almost beveled way. On my 44 inch led tv at 1080p this shader is just a dream to look at.

[QUOTE=tekn0;33158]beam_horiz_filter = β€œ0.000000” beam_horiz_sigma = β€œ0.545000”[/QUOTE]

Someone correct me if I’m wrong but that sigma value will only be used if you set the filter to 1.0.


//  What filter should be used to sample scanlines horizontally?    //  0: Quilez (fast), 1: Gaussian (configurable), 2: Lanczos2 (sharp)
static const float beam_horiz_filter_static = 2.0;
//  Standard deviation for horizontal Gaussian resampling:
static const float beam_horiz_sigma_static = 0.545000;      //  range (0, 2/3]

Also BVMs, and most CRTs, have a gamma of 2.4, not 2.5

Hi,

First time poster…these settings are amazing. I’d never wanted to use to libretro cores due to adding another layer to my frontend but the shaders alone have hooked me.

Could someone tell me if this gpu has enough muscle to run this shader at these settings?

I think it should be okay. If not, you can gain a good bit of performance by disabling runtime parameters and hardcoding settings into the user-settings.h file. This one should do it:

#ifndef USER_SETTINGS_H
#define USER_SETTINGS_H

/////////////////////////////  DRIVER CAPABILITIES  ////////////////////////////

//  The Cg compiler uses different "profiles" with different capabilities.
//  This shader requires a Cg compilation profile >= arbfp1, but a few options
//  require higher profiles like fp30 or fp40.  The shader can't detect profile
//  or driver capabilities, so instead you must comment or uncomment the lines
//  below with "//" before "#define."  Disable an option if you get compilation
//  errors resembling those listed.  Generally speaking, all of these options
//  will run on nVidia cards, but only DRIVERS_ALLOW_TEX2DBIAS (if that) is
//  likely to run on ATI/AMD, due to the Cg compiler's profile limitations.

//  Derivatives: Unsupported on fp20, ps_1_1, ps_1_2, ps_1_3, and arbfp1.
//  Among other things, derivatives help us fix anisotropic filtering artifacts
//  with curved manually tiled phosphor mask coords.  Related errors:
//  error C3004: function "float2 ddx(float2);" not supported in this profile
//  error C3004: function "float2 ddy(float2);" not supported in this profile
    //#define DRIVERS_ALLOW_DERIVATIVES

//  Fine derivatives: Unsupported on older ATI cards.
//  Fine derivatives enable 2x2 fragment block communication, letting us perform
//  fast single-pass blur operations.  If your card uses coarse derivatives and
//  these are enabled, blurs could look broken.  Derivatives are a prerequisite.
    #ifdef DRIVERS_ALLOW_DERIVATIVES
        #define DRIVERS_ALLOW_FINE_DERIVATIVES
    #endif

//  Dynamic looping: Requires an fp30 or newer profile.
//  This makes phosphor mask resampling faster in some cases.  Related errors:
//  error C5013: profile does not support "for" statements and "for" could not
//  be unrolled
    //#define DRIVERS_ALLOW_DYNAMIC_BRANCHES

//  Without DRIVERS_ALLOW_DYNAMIC_BRANCHES, we need to use unrollable loops.
//  Using one static loop avoids overhead if the user is right, but if the user
//  is wrong (loops are allowed), breaking a loop into if-blocked pieces with a
//  binary search can potentially save some iterations.  However, it may fail:
//  error C6001: Temporary register limit of 32 exceeded; 35 registers
//  needed to compile program
    //#define ACCOMODATE_POSSIBLE_DYNAMIC_LOOPS

//  tex2Dlod: Requires an fp40 or newer profile.  This can be used to disable
//  anisotropic filtering, thereby fixing related artifacts.  Related errors:
//  error C3004: function "float4 tex2Dlod(sampler2D, float4);" not supported in
//  this profile
    //#define DRIVERS_ALLOW_TEX2DLOD

//  tex2Dbias: Requires an fp30 or newer profile.  This can be used to alleviate
//  artifacts from anisotropic filtering and mipmapping.  Related errors:
//  error C3004: function "float4 tex2Dbias(sampler2D, float4);" not supported
//  in this profile
    //#define DRIVERS_ALLOW_TEX2DBIAS

//  Integrated graphics compatibility: Integrated graphics like Intel HD 4000
//  impose stricter limitations on register counts and instructions.  Enable
//  INTEGRATED_GRAPHICS_COMPATIBILITY_MODE if you still see error C6001 or:
//  error C6002: Instruction limit of 1024 exceeded: 1523 instructions needed
//  to compile program.
//  Enabling integrated graphics compatibility mode will automatically disable:
//  1.) PHOSPHOR_MASK_MANUALLY_RESIZE: The phosphor mask will be softer.
//      (This may be reenabled in a later release.)
//  2.) RUNTIME_GEOMETRY_MODE
//  3.) The high-quality 4x4 Gaussian resize for the bloom approximation
    //#define INTEGRATED_GRAPHICS_COMPATIBILITY_MODE


////////////////////////////  USER CODEPATH OPTIONS  ///////////////////////////

//  To disable a #define option, turn its line into a comment with "//."

//  RUNTIME VS. COMPILE-TIME OPTIONS (Major Performance Implications):
//  Enable runtime shader parameters in the Retroarch (etc.) GUI?  They override
//  many of the options in this file and allow real-time tuning, but many of
//  them are slower.  Disabling them and using this text file will boost FPS.
//#define RUNTIME_SHADER_PARAMS_ENABLE
//  Specify the phosphor bloom sigma at runtime?  This option is 10% slower, but
//  it's the only way to do a wide-enough full bloom with a runtime dot pitch.
//#define RUNTIME_PHOSPHOR_BLOOM_SIGMA
//  Specify antialiasing weight parameters at runtime?  (Costs ~20% with cubics)
//#define RUNTIME_ANTIALIAS_WEIGHTS
//  Specify subpixel offsets at runtime? (WARNING: EXTREMELY EXPENSIVE!)
//#define RUNTIME_ANTIALIAS_SUBPIXEL_OFFSETS
//  Make beam_horiz_filter and beam_horiz_linear_rgb_weight into runtime shader
//  parameters?  This will require more math or dynamic branching.
//#define RUNTIME_SCANLINES_HORIZ_FILTER_COLORSPACE
//  Specify the tilt at runtime?  This makes things about 3% slower.
//#define RUNTIME_GEOMETRY_TILT
//  Specify the geometry mode at runtime?
//#define RUNTIME_GEOMETRY_MODE
//  Specify the phosphor mask type (aperture grille, slot mask, shadow mask) and
//  mode (Lanczos-resize, hardware resize, or tile 1:1) at runtime, even without
//  dynamic branches?  This is cheap if mask_resize_viewport_scale is small.
//#define FORCE_RUNTIME_PHOSPHOR_MASK_MODE_TYPE_SELECT

//  PHOSPHOR MASK:
//  Manually resize the phosphor mask for best results (slower)?  Disabling this
//  removes the option to do so, but it may be faster without dynamic branches.
//    #define PHOSPHOR_MASK_MANUALLY_RESIZE
//  If we sinc-resize the mask, should we Lanczos-window it (slower but better)?
//    #define PHOSPHOR_MASK_RESIZE_LANCZOS_WINDOW
//  Larger blurs are expensive, but we need them to blur larger triads.  We can
//  detect the right blur if the triad size is static or our profile allows
//  dynamic branches, but otherwise we use the largest blur the user indicates
//  they might need:
    #define PHOSPHOR_BLOOM_TRIADS_LARGER_THAN_3_PIXELS
    //#define PHOSPHOR_BLOOM_TRIADS_LARGER_THAN_6_PIXELS
    //#define PHOSPHOR_BLOOM_TRIADS_LARGER_THAN_9_PIXELS
    //#define PHOSPHOR_BLOOM_TRIADS_LARGER_THAN_12_PIXELS
    //  Here's a helpful chart:
    //  MaxTriadSize    BlurSize    MinTriadCountsByResolution
    //  3.0             9.0         480/640/960/1920 triads at 1080p/1440p/2160p/4320p, 4:3 aspect
    //  6.0             17.0        240/320/480/960 triads at 1080p/1440p/2160p/4320p, 4:3 aspect
    //  9.0             25.0        160/213/320/640 triads at 1080p/1440p/2160p/4320p, 4:3 aspect
    //  12.0            31.0        120/160/240/480 triads at 1080p/1440p/2160p/4320p, 4:3 aspect
    //  18.0            43.0        80/107/160/320 triads at 1080p/1440p/2160p/4320p, 4:3 aspect


///////////////////////////////  USER PARAMETERS  //////////////////////////////

//  Note: Many of these static parameters are overridden by runtime shader
//  parameters when those are enabled.  However, many others are static codepath
//  options that were cleaner or more convert to code as static constants.

//  GAMMA:
    static const float crt_gamma_static = 2.5;                  //  range [1, 5]
    static const float lcd_gamma_static = 2.2;                  //  range [1, 5]

//  LEVELS MANAGEMENT:
    //  Control the final multiplicative image contrast:
    static const float levels_contrast_static = 0.75;            //  range [0, 4)
    //  We auto-dim to avoid clipping between passes and restore brightness
    //  later.  Control the dim factor here: Lower values clip less but crush
    //  blacks more (static only for now).
    static const float levels_autodim_temp = 0.5;               //  range (0, 1]

//  HALATION/DIFFUSION/BLOOM:
    //  Halation weight: How much energy should be lost to electrons bounding
    //  around under the CRT glass and exciting random phosphors?
    static const float halation_weight_static = 0.0;            //  range [0, 1]
    //  Refractive diffusion weight: How much light should spread/diffuse from
    //  refracting through the CRT glass?
    static const float diffusion_weight_static = 0.01;         //  range [0, 1]
    //  Underestimate brightness: Bright areas bloom more, but we can base the
    //  bloom brightpass on a lower brightness to sharpen phosphors, or a higher
    //  brightness to soften them.  Low values clip, but >= 0.8 looks okay.
    static const float bloom_underestimate_levels_static = 0.8; //  range [0, 5]
    //  Blur all colors more than necessary for a softer phosphor bloom?
    static const float bloom_excess_static = 0.0;               //  range [0, 1]
    //  The BLOOM_APPROX pass approximates a phosphor blur early on with a small
    //  blurred resize of the input (convergence offsets are applied as well).
    //  There are three filter options (static option only for now):
    //  0.) Bilinear resize: A fast, close approximation to a 4x4 resize
    //      if min_allowed_viewport_triads and the BLOOM_APPROX resolution are sane
    //      and beam_max_sigma is low.
    //  1.) 3x3 resize blur: Medium speed, soft/smeared from bilinear blurring,
    //      always uses a static sigma regardless of beam_max_sigma or
    //      mask_num_triads_desired.
    //  2.) True 4x4 Gaussian resize: Slowest, technically correct.
    //  These options are more pronounced for the fast, unbloomed shader version.
    static const float bloom_approx_filter_static = 1.0;

//  ELECTRON BEAM SCANLINE DISTRIBUTION:
    //  How many scanlines should contribute light to each pixel?  Using more
    //  scanlines is slower (especially for a generalized Gaussian) but less
    //  distorted with larger beam sigmas (especially for a pure Gaussian).  The
    //  max_beam_sigma at which the closest unused weight is guaranteed <
    //  1.0/255.0 (for a 3x antialiased pure Gaussian) is:
    //      2 scanlines: max_beam_sigma = 0.2089; distortions begin ~0.34; 141.7 FPS pure, 131.9 FPS generalized
    //      3 scanlines, max_beam_sigma = 0.3879; distortions begin ~0.52; 137.5 FPS pure; 123.8 FPS generalized
    //      4 scanlines, max_beam_sigma = 0.5723; distortions begin ~0.70; 134.7 FPS pure; 117.2 FPS generalized
    //      5 scanlines, max_beam_sigma = 0.7591; distortions begin ~0.89; 131.6 FPS pure; 112.1 FPS generalized
    //      6 scanlines, max_beam_sigma = 0.9483; distortions begin ~1.08; 127.9 FPS pure; 105.6 FPS generalized
    static const float beam_num_scanlines = 2.0;                //  range [2, 6]
    //  A generalized Gaussian beam varies shape with color too, now just width.
    //  It's slower but more flexible (static option only for now).
    static const bool beam_generalized_gaussian = true;
    //  What kind of scanline antialiasing do you want?
    //  0: Sample weights at 1x; 1: Sample weights at 3x; 2: Compute an integral
    //  Integrals are slow (especially for generalized Gaussians) and rarely any
    //  better than 3x antialiasing (static option only for now).
    static const float beam_antialias_level = 1.0;              //  range [0, 2]
    //  Min/max standard deviations for scanline beams: Higher values widen and
    //  soften scanlines.  Depending on other options, low min sigmas can alias.
    static const float beam_min_sigma_static = 0.015;            //  range (0, 1]
    static const float beam_max_sigma_static = 0.2;             //  range (0, 1]
    //  Beam width varies as a function of color: A power function (0) is more
    //  configurable, but a spherical function (1) gives the widest beam
    //  variability without aliasing (static option only for now).
    static const float beam_spot_shape_function = 1.0;
    //  Spot shape power: Powers <= 1 give smoother spot shapes but lower
    //  sharpness.  Powers >= 1.0 are awful unless mix/max sigmas are close.
    static const float beam_spot_power_static = 0.33;    //  range (0, 16]
    //  Generalized Gaussian max shape parameters: Higher values give flatter
    //  scanline plateaus and steeper dropoffs, simultaneously widening and
    //  sharpening scanlines at the cost of aliasing.  2.0 is pure Gaussian, and
    //  values > ~40.0 cause artifacts with integrals.
    static const float beam_min_shape_static = 2.0;         //  range [2, 32]
    static const float beam_max_shape_static = 4.0;         //  range [2, 32]
    //  Generalized Gaussian shape power: Affects how quickly the distribution
    //  changes shape from Gaussian to steep/plateaued as color increases from 0
    //  to 1.0.  Higher powers appear softer for most colors, and lower powers
    //  appear sharper for most colors.
    static const float beam_shape_power_static = 0.25;   //  range (0, 16]
    //  What filter should be used to sample scanlines horizontally?
    //  0: Quilez (fast), 1: Gaussian (configurable), 2: Lanczos2 (sharp)
    static const float beam_horiz_filter_static = 0.0;
    //  Standard deviation for horizontal Gaussian resampling:
    static const float beam_horiz_sigma_static = 0.545;      //  range (0, 2/3]
    //  Do horizontal scanline sampling in linear RGB (correct light mixing),
    //  gamma-encoded RGB (darker, hard spot shape, may better match bandwidth-
    //  limiting circuitry in some CRT's), or a weighted avg.?
    static const float beam_horiz_linear_rgb_weight_static = 1.0;   //  range [0, 1]
    //  Simulate scanline misconvergence?  This needs 3x horizontal texture
    //  samples and 3x texture samples of BLOOM_APPROX and HALATION_BLUR in
    //  later passes (static option only for now).
    static const bool beam_misconvergence = true;
    //  Convergence offsets in x/y directions for R/G/B scanline beams in units
    //  of scanlines.  Positive offsets go right/down; ranges [-2, 2]
    static const float2 convergence_offsets_r_static = float2(0.0, 0.1);
    static const float2 convergence_offsets_g_static = float2(0.0, -0.1);
    static const float2 convergence_offsets_b_static = float2(0.0, 0.1);
    //  Detect interlacing (static option only for now)?
    static const bool interlace_detect = true;
    //  Assume 1080-line sources are interlaced?
    static const bool interlace_1080i_static = false;
    //  For interlaced sources, assume TFF (top-field first) or BFF order?
    //  (Whether this matters depends on the nature of the interlaced input.)
    static const bool interlace_bff_static = false;

//  ANTIALIASING:
    //  What AA level do you want for curvature/overscan/subpixels?  Options:
    //  0x (none), 1x (sample subpixels), 4x, 5x, 6x, 7x, 8x, 12x, 16x, 20x, 24x
    //  (Static option only for now)
    static const float aa_level = 4.0;                     //  range [0, 24]
    //  What antialiasing filter do you want (static option only)?  Options:
    //  0: Box (separable), 1: Box (cylindrical),
    //  2: Tent (separable), 3: Tent (cylindrical),
    //  4: Gaussian (separable), 5: Gaussian (cylindrical),
    //  6: Cubic* (separable), 7: Cubic* (cylindrical, poor)
    //  8: Lanczos Sinc (separable), 9: Lanczos Jinc (cylindrical, poor)
    //      * = Especially slow with RUNTIME_ANTIALIAS_WEIGHTS
    static const float aa_filter = 5.0;                     //  range [0, 9]
    //  Flip the sample grid on odd/even frames (static option only for now)?
    static const bool aa_temporal = true;
    //  Use RGB subpixel offsets for antialiasing?  The pixel is at green, and
    //  the blue offset is the negative r offset; range [0, 0.5]
    static const float2 aa_subpixel_r_offset_static = float2(-1.0/3.0, 0.0);//float2(0.0);
    //  Cubics: See http://www.imagemagick.org/Usage/filter/#mitchell
    //  1.) "Keys cubics" with B = 1 - 2C are considered the highest quality.
    //  2.) C = 0.5 (default) is Catmull-Rom; higher C's apply sharpening.
    //  3.) C = 1.0/3.0 is the Mitchell-Netravali filter.
    //  4.) C = 0.0 is a soft spline filter.
    static const float aa_cubic_c_static = 0.5;             //  range [0, 4]
    //  Standard deviation for Gaussian antialiasing: Try 0.5/aa_pixel_diameter.
    static const float aa_gauss_sigma_static = 0.5;     //  range [0.0625, 1.0]

//  PHOSPHOR MASK:
    //  Mask type: 0 = aperture grille, 1 = slot mask, 2 = EDP shadow mask
    static const float mask_type_static = 0.0;                  //  range [0, 2]
    //  We can sample the mask three ways.  Pick 2/3 from: Pretty/Fast/Flexible.
    //  0.) Sinc-resize to the desired dot pitch manually (pretty/slow/flexible).
    //      This requires PHOSPHOR_MASK_MANUALLY_RESIZE to be #defined.
    //  1.) Hardware-resize to the desired dot pitch (ugly/fast/flexible).  This
    //      is halfway decent with LUT mipmapping but atrocious without it.
    //  2.) Tile it without resizing at a 1:1 texel:pixel ratio for flat coords
    //      (pretty/fast/inflexible).  Each input LUT has a fixed dot pitch.
    //      This mode reuses the same masks, so triads will be enormous unless
    //      you change the mask LUT filenames in your .cgp file.
    static const float mask_sample_mode_static = 1.0;           //  range [0, 2]
    //  Prefer setting the triad size (0.0) or number on the screen (1.0)?
    //  If RUNTIME_PHOSPHOR_BLOOM_SIGMA isn't #defined, the specified triad size
    //  will always be used to calculate the full bloom sigma statically.
    static const float mask_specify_num_triads_static = 1.0;    //  range [0, 1]
    //  Specify the phosphor triad size, in pixels.  Each tile (usually with 8
    //  triads) will be rounded to the nearest integer tile size and clamped to
    //  obey minimum size constraints (imposed to reduce downsize taps) and
    //  maximum size constraints (imposed to have a sane MASK_RESIZE FBO size).
    //  To increase the size limit, double the viewport-relative scales for the
    //  two MASK_RESIZE passes in crt-royale.cgp and user-cgp-contants.h.
    //      range [1, mask_texture_small_size/mask_triads_per_tile]
    static const float mask_triad_size_desired_static = 24.0 / 8.0;
    //  If mask_specify_num_triads is 1.0/true, we'll go by this instead (the
    //  final size will be rounded and constrained as above); default 480.0
    static const float mask_num_triads_desired_static = 800.0;
    //  How many lobes should the sinc/Lanczos resizer use?  More lobes require
    //  more samples and avoid moire a bit better, but some is unavoidable
    //  depending on the destination size (static option for now).
    static const float mask_sinc_lobes = 2.0;                   //  range [2, 4]
    //  The mask is resized using a variable number of taps in each dimension,
    //  but some Cg profiles always fetch a constant number of taps no matter
    //  what (no dynamic branching).  We can limit the maximum number of taps if
    //  we statically limit the minimum phosphor triad size.  Larger values are
    //  faster, but the limit IS enforced (static option only, forever);
    //      range [1, mask_texture_small_size/mask_triads_per_tile]
    //  TODO: Make this 1.0 and compensate with smarter sampling!
    static const float mask_min_allowed_triad_size = 2.0;

//  GEOMETRY:
    //  Geometry mode:
    //  0: Off (default), 1: Spherical mapping (like cgwg's),
    //  2: Alt. spherical mapping (more bulbous), 3: Cylindrical/Trinitron
    static const float geom_mode_static = 0.0;      //  range [0, 3]
    //  Radius of curvature: Measured in units of your viewport's diagonal size.
    static const float geom_radius_static = 2.0;    //  range [1/(2*pi), 1024]
    //  View dist is the distance from the player to their physical screen, in
    //  units of the viewport's diagonal size.  It controls the field of view.
    static const float geom_view_dist_static = 2.0; //  range [0.5, 1024]
    //  Tilt angle in radians (clockwise around up and right vectors):
    static const float2 geom_tilt_angle_static = float2(0.0, 0.0);  //  range [-pi, pi]
    //  Aspect ratio: When the true viewport size is unknown, this value is used
    //  to help convert between the phosphor triad size and count, along with
    //  the mask_resize_viewport_scale constant from user-cgp-constants.h.  Set
    //  this equal to Retroarch's display aspect ratio (DAR) for best results;
    //  range [1, geom_max_aspect_ratio from user-cgp-constants.h];
    //  default (256/224)*(54/47) = 1.313069909 (see below)
    static const float geom_aspect_ratio_static = 1.313069909;
    //  Before getting into overscan, here's some general aspect ratio info:
    //  - DAR = display aspect ratio = SAR * PAR; as in your Retroarch setting
    //  - SAR = storage aspect ratio = DAR / PAR; square pixel emulator frame AR
    //  - PAR = pixel aspect ratio   = DAR / SAR; holds regardless of cropping
    //  Geometry processing has to "undo" the screen-space 2D DAR to calculate
    //  3D view vectors, then reapplies the aspect ratio to the simulated CRT in
    //  uv-space.  To ensure the source SAR is intended for a ~4:3 DAR, either:
    //  a.) Enable Retroarch's "Crop Overscan"
    //  b.) Readd horizontal padding: Set overscan to e.g. N*(1.0, 240.0/224.0)
    //  Real consoles use horizontal black padding in the signal, but emulators
    //  often crop this without cropping the vertical padding; a 256x224 [S]NES
    //  frame (8:7 SAR) is intended for a ~4:3 DAR, but a 256x240 frame is not.
    //  The correct [S]NES PAR is 54:47, found by blargg and NewRisingSun:
    //      http://board.zsnes.com/phpBB3/viewtopic.php?f=22&t=11928&start=50
    //      http://forums.nesdev.com/viewtopic.php?p=24815#p24815
    //  For flat output, it's okay to set DAR = [existing] SAR * [correct] PAR
    //  without doing a. or b., but horizontal image borders will be tighter
    //  than vertical ones, messing up curvature and overscan.  Fixing the
    //  padding first corrects this.
    //  Overscan: Amount to "zoom in" before cropping.  You can zoom uniformly
    //  or adjust x/y independently to e.g. readd horizontal padding, as noted
    //  above: Values < 1.0 zoom out; range (0, inf)
    static const float2 geom_overscan_static = float2(1.0, 1.0);// * 1.005 * (1.0, 240/224.0)
    //  Compute a proper pixel-space to texture-space matrix even without ddx()/
    //  ddy()?  This is ~8.5% slower but improves antialiasing/subpixel filtering
    //  with strong curvature (static option only for now).
    static const bool geom_force_correct_tangent_matrix = false;

//  BORDERS:
    //  Rounded border size in texture uv coords:
    static const float border_size_static = 0.005;           //  range [0, 0.5]
    //  Border darkness: Moderate values darken the border smoothly, and high
    //  values make the image very dark just inside the border:
    static const float border_darkness_static = 0.0;        //  range [0, inf)
    //  Border compression: High numbers compress border transitions, narrowing
    //  the dark border area.
    static const float border_compress_static = 2.5;        //  range [1, inf)


#endif  //  USER_SETTINGS_H

Whoa that’s a lot!..

Thanks, hunterk!

These are a nicest Royale settings I found so far as well. I don’t think there is much to improve other than slight tweaks. I’ll post my update if I can improve it.

He did make a few tweaks and updated the settings, since you posted. So, for now here is Kurozumi’s updated settings:

crt_gamma = β€œ2.500000” lcd_gamma = β€œ2.400000” levels_contrast = β€œ0.840000” halation_weight = β€œ0.000000” diffusion_weight = β€œ0.010000” bloom_underestimate_levels = β€œ0.800000” bloom_excess = β€œ0.000000” beam_min_sigma = β€œ0.02000” beam_max_sigma = β€œ0.200000” beam_spot_power = β€œ0.370000” beam_min_shape = β€œ2.000000” beam_max_shape = β€œ4.000000” beam_shape_power = β€œ0.250000” beam_horiz_filter = β€œ0.000000” beam_horiz_sigma = β€œ0.545000” beam_horiz_linear_rgb_weight = β€œ1.000000” convergence_offset_x_r = β€œ0.000000” convergence_offset_x_g = β€œ0.000000” convergence_offset_x_b = β€œ0.000000” convergence_offset_y_r = β€œ0.100000” convergence_offset_y_g = β€œ-0.100000” convergence_offset_y_b = β€œ0.100000” mask_type = β€œ0.000000” mask_sample_mode_desired = β€œ0.000000” mask_specify_num_triads = β€œ1.000000” mask_triad_size_desired = β€œ3.000000” mask_num_triads_desired = β€œ900.000000” aa_subpixel_r_offset_x_runtime = β€œ-0.333333” aa_subpixel_r_offset_y_runtime = β€œ0.000000” aa_cubic_c = β€œ0.500000” aa_gauss_sigma = β€œ0.500000” geom_mode_runtime = β€œ3.000000” geom_radius = β€œ3.000000” geom_view_dist = β€œ2.000000” geom_tilt_angle_x = β€œ0.000000” geom_tilt_angle_y = β€œ0.000000” geom_aspect_ratio_x = β€œ432.000000” geom_aspect_ratio_y = β€œ329.000000” geom_overscan_x = β€œ1.000000” geom_overscan_y = β€œ1.000000” border_size = β€œ0.005000” border_darkness = β€œ0.000000” border_compress = β€œ2.500000” interlace_bff = β€œ0.000000” interlace_1080i = β€œ0.000000”

The latest version of this is looking really good now. I wouldn’t mind if the scanlines were a bit thicker, but I like the way that it blooms the scanline width a lot more than the Royale defaults.

As with all Royale presets, the brightness really needs to come down a lot to avoid clipping. In doing some quick tests with Metal Slug 2, I had to reduce levels_contrast to 0.47 and it would probably be safer to set it even lower than that.

A lot of people don’t seem to understand that scanlines have to reduce the image brightness by a considerable amount. If you use basic scanlines that simply black out every other line, your image should now be half its original brightness. Anything you try to do in a shader to compensate for that is going to clip or distort the colors in a bad way. When you enable scanlines, you should be turning up your monitor’s backlight to compensate for the loss of brightness instead of trying to do it in software.

With the brightness of these images normalized, it becomes easier to see the difference: [ul] [li]levels_contrast 0.84 (clipped) [/li][li]levels_contrast 0.50 (minimal clipping) [/li][li]Original Pixels [/li][/ul] I’m not sure how obvious it will be in the comparison, but with the clipped image you should see that the bright areas look flat, while they still have definition and β€œglow” in the second image. There’s also a color tint to the image as a result of clipping.

Obviously these will look dull at your monitor’s normal brightness, but if you turn up the backlight, it should stop looking dull. Of course that assumes your monitor is set at a normal brightness, instead of always using it at its highest brightness. In that case there’s nothing you can do. (except get a monitor that’s twice as bright)

1 Like

How would I make the scanlines darker and take away some of the blur so the image is sharper, exactly which values? Dropping the Beam Max Sigma takes away blur but also darkens it or something. Raising the aa_cubic_c sharpens it but looks artificial. The darkening of scanlines I can’t seem to figure out unless that’s just contrast? Your 0.50 minimal clipping screenshot looks good. I will try both adjusting the backlight and trying shader tweak for compensating of darkness.

what did you change to get this: levels_contrast 0.50 (minimal clipping) ? Just contrast? looks sharper than mine also.

The β€œblur” is required for this type of shader - it’s anti-aliasing. (removes flicker/distortion) The higher resolution your display is, the sharper it should be. You can’t really get around that.

If you set the convergence offsets to 0 it should appear to be a bit sharper at least. Setting geom_mode_runtime to 0 will also be sharper, but more aliased - especially if you use non-integer scaling.

[QUOTE=larch1991;38416]The β€œblur” is required for this type of shader - it’s anti-aliasing. (removes flicker/distortion) The higher resolution your display is, the sharper it should be. You can’t really get around that.

If you set the convergence offsets to 0 it should appear to be a bit sharper at least. Setting geom_mode_runtime to 0 will also be sharper, but more aliased - especially if you use non-integer scaling.[/QUOTE]

Ok, cool thanks. Yeah my 47 inch Sony monitor is only 1080p, although I can use DSR but not sure if it would help. I set the contrast to 0.50 and turned off the curved screen with geom mode. It is sharper. Disabling the convergence didn’t seem to make a difference noticeably for me, as 0.10 is pretty low… at least for NES. Still looks like it should be sharper compared to actual SD CRT TV RGB, Sony BVM/PVM or Arcade Monitors, although it may not be possible other than increasing the AA cubic sharpness. Anything else? Seems aspect ratio for NES looks more like the original if set to 1:1 PAR rather than 4:3, but the width seems a bit too thin. I do use Interger Scaling ON as well.

EDIT: Shame you can’t use the geom mode without any blurriness. It looked nice with a slight curve similar to a BVM.

Hi guys… iΒ΄ve been following the whole crt shader thing for a while now. Crt Royale Kurozumi looks really stunning. I think you guys should write some kind of guide about crt shading, covering the hot topics just to explain to newcomers… some of them just donΒ΄t know what theyΒ΄re missing.

The only complain I have for this shader is that I seem to have some sort of problem as soon as vertical scrolling is implied. Like moire effect (donΒ΄t know exactly how to call it, just something is wrong with the scanlines, like they become more visible and some of them appear to be irregular).

IΒ΄m pretty much sure that you have the solution for this. IΒ΄ve tweaked some of the settings (for instance, I prefer much lower gamma) and it seems to reduce the issue but it wonΒ΄t go completely away. On the other hand, crt hyllian (another awesome shader) doesnΒ΄t seem to suffer from this, at least here.