New CRT shader from Guest + CRT Guest Advanced updates

Ah, thanks. Also, what should the Mask gamma be? Same as gamma_in or gamma_out (I use 2.2 here)?

1 Like

Edit…oppsie, mask gamma. Lowering mask gamma produces a more coarse effect and greater neighbour pixel contrast. It’s really mask and taste/situation dependent. If you would use a normal png mask without linearization it would be equivalent to mask gamma 1.0.

Hey there! Normal is quite nice at 1440p and 4k also. The catch with hi-res version is a broader horizontal filter, so you can have some degree of smoothness with high resolution content, plus some specific features like internal resolution and red-blue deconvergence.

You can also try to change the mask gamma, i guess increasing it should do the trick in your situation. The downside is not too big, the contrast between adjacent output pixels is smaller and the overall image is brighter. Imo it’s quite important to be able to set the right amount of image brightness.

4 Likes

Thank you! I’m pretty happy with things now on the CRT side of things. The hires internal resolution feature was a life saver for the PSP. The PSP is awkward because it technically uses an LCD but most the games I play are ported from PS1/SNES (tactics games) so they all benefit from your filter.

Issue I was having was the psp needing an internal resolution increase to counter the need for a linier filter as it would have really odd pixel output without one. The resolution being so high was keeping me from using any CRT filters on it, but with the hires feature I actually have it all set up now!

Now to find a good handheld (gba/ds) LCD grid and scaling method, really not a fan of the fat grids I see out there.

1 Like

Thank you for this fix! I thought my mind was playing tricks on me because I noticed that in motion games would look sharper and pixelated, which I couldn’t figure out because still screenshots of the newer and older versions of GDV looked the same. Glad it wasn’t just me :sweat_smile::grin:

1 Like

Playing around with sharpness settings some more. I like this combo because it eliminates the artifacts resulting from subtractive sharpness while still keeping edges reasonably sharp. The scanlines look very natural on my plasma TV.

scanline spike removal 1.00
subtractive sharpness 0.50
horizontal sharpness 4.00

3 Likes

I’ve been enjoying my current iteration of Venom 2 on my 1080p 14 inch laptop. I’ve pushed the mask gamma along with the Mask Low strength to exaggerate the masking in the darks while leaving the brights untouched. This gives me increased contrast that doesn’t crush the image. It may not be realistic but I find it very pleasing:

shaders = "9"
shader0 = "shaders_slang/sharpen/shaders/fast-sharpen.slang"
filter_linear0 = "true"
wrap_mode0 = "clamp_to_border"
mipmap_input0 = "false"
alias0 = ""
float_framebuffer0 = "false"
srgb_framebuffer0 = "false"
scale_type_x0 = "source"
scale_x0 = "1.000000"
scale_type_y0 = "source"
scale_y0 = "1.000000"
shader1 = "shaders_slang/misc/grade.slang"
filter_linear1 = "true"
wrap_mode1 = "clamp_to_border"
mipmap_input1 = "false"
alias1 = "StockPass"
float_framebuffer1 = "false"
srgb_framebuffer1 = "false"
scale_type_x1 = "source"
scale_x1 = "1.000000"
scale_type_y1 = "source"
scale_y1 = "1.000000"
shader2 = "shaders_slang/crt/shaders/guest/crt-gdv-new/afterglow0.slang"
filter_linear2 = "true"
wrap_mode2 = "clamp_to_border"
mipmap_input2 = "false"
alias2 = "AfterglowPass"
float_framebuffer2 = "false"
srgb_framebuffer2 = "false"
scale_type_x2 = "source"
scale_x2 = "1.000000"
scale_type_y2 = "source"
scale_y2 = "1.000000"
shader3 = "shaders_slang/crt/shaders/guest/crt-gdv-new/pre-shaders-afterglow.slang"
filter_linear3 = "true"
wrap_mode3 = "clamp_to_border"
mipmap_input3 = "false"
alias3 = "PrePass"
float_framebuffer3 = "false"
srgb_framebuffer3 = "false"
scale_type_x3 = "source"
scale_x3 = "1.000000"
scale_type_y3 = "source"
scale_y3 = "1.000000"
shader4 = "shaders_slang/crt/shaders/guest/crt-gdv-new/avg-lum.slang"
filter_linear4 = "true"
wrap_mode4 = "clamp_to_border"
mipmap_input4 = "true"
alias4 = "AvgLumPass"
float_framebuffer4 = "false"
srgb_framebuffer4 = "false"
scale_type_x4 = "source"
scale_x4 = "1.000000"
scale_type_y4 = "source"
scale_y4 = "1.000000"
shader5 = "shaders_slang/crt/shaders/guest/crt-gdv-new/linearize.slang"
filter_linear5 = "true"
wrap_mode5 = "clamp_to_border"
mipmap_input5 = "false"
alias5 = "LinearizePass"
float_framebuffer5 = "true"
srgb_framebuffer5 = "false"
scale_type_x5 = "source"
scale_x5 = "1.000000"
scale_type_y5 = "source"
scale_y5 = "1.000000"
shader6 = "shaders_slang/crt/shaders/guest/crt-gdv-new/gaussian_horizontal.slang"
filter_linear6 = "true"
wrap_mode6 = "clamp_to_border"
mipmap_input6 = "false"
alias6 = ""
float_framebuffer6 = "false"
srgb_framebuffer6 = "false"
shader7 = "shaders_slang/crt/shaders/guest/crt-gdv-new/gaussian_vertical.slang"
filter_linear7 = "true"
wrap_mode7 = "clamp_to_border"
mipmap_input7 = "false"
alias7 = "GlowPass"
float_framebuffer7 = "false"
srgb_framebuffer7 = "false"
scale_type_x7 = "viewport"
scale_x7 = "0.500000"
scale_type_y7 = "viewport"
scale_y7 = "0.500000"
shader8 = "shaders_slang/crt/shaders/guest/crt-gdv-new/crt-guest-dr-venom2.slang"
filter_linear8 = "true"
wrap_mode8 = "clamp_to_border"
mipmap_input8 = "false"
alias8 = ""
float_framebuffer8 = "false"
srgb_framebuffer8 = "false"
scale_type_x8 = "viewport"
scale_x8 = "1.000000"
scale_type_y8 = "viewport"
scale_y8 = "1.000000"
parameters = "SHARPEN;CONTR;DETAILS;g_gamma_in;g_signal_type;g_gamma_type;g_crtgamut;g_space_out;g_hue_degrees;g_I_SHIFT;g_Q_SHIFT;g_I_MUL;g_Q_MUL;g_lum_fix;g_vignette;g_vstr;g_vpower;g_lum;g_cntrst;g_mid;wp_temperature;g_sat;g_vibr;g_satr;g_satg;g_satb;g_lift;blr;blg;blb;wlr;wlg;wlb;rg;rb;gr;gb;br;bg;LUT_Size1;LUT1_toggle;LUT_Size2;LUT2_toggle;bogus_afterglow;PR;PG;PB;AS;sat;bogus_color;TNTC;LS;LUTLOW;LUTBR;CP;CS;WP;wp_saturation;lsmooth;GAMMA_INPUT;bogus_interlacing;inter;interm;inters;iscan;bogus_glow;SIZEH;SIGMA_H;SIZEV;SIGMA_V;bogus_brightness;glow;bloom;gamma_c;brightboost;brightboost1;bogus_scanline;gsl;scanline1;scanline2;beam_min;beam_max;beam_size;vertmask;scans;spike;bogus_filtering;h_sharp;s_sharp;smart_ei;ei_limit;sth;bogus_screen;TATE;IOS;OS;BLOOM;csize;bsize;warpX;warpY;bogus_masks;shadowMask;maskstr;masksize;maskDark;maskLight;mcut;mask_gamma;slotmask;slotwidth;double_slot;slotms;mclip;gamma_out"
SHARPEN = "0.150000"
CONTR = "0.250000"
DETAILS = "1.000000"
g_gamma_in = "2.600000"
g_signal_type = "1.000000"
g_gamma_type = "1.000000"
g_crtgamut = "2.000000"
g_space_out = "0.000000"
g_hue_degrees = "0.000000"
g_I_SHIFT = "0.000000"
g_Q_SHIFT = "0.000000"
g_I_MUL = "1.000000"
g_Q_MUL = "1.000000"
g_lum_fix = "0.000000"
g_vignette = "0.000000"
g_vstr = "40.000000"
g_vpower = "0.200000"
g_lum = "0.000000"
g_cntrst = "-0.050000"
g_mid = "0.000000"
wp_temperature = "7604.000000"
g_sat = "0.000000"
g_vibr = "0.000000"
g_satr = "0.000000"
g_satg = "0.000000"
g_satb = "0.000000"
g_lift = "0.000000"
blr = "0.000000"
blg = "0.000000"
blb = "0.000000"
wlr = "1.000000"
wlg = "1.000000"
wlb = "1.000000"
rg = "0.000000"
rb = "0.000000"
gr = "0.000000"
gb = "0.000000"
br = "0.000000"
bg = "0.000000"
LUT_Size1 = "32.000000"
LUT1_toggle = "0.000000"
LUT_Size2 = "32.000000"
LUT2_toggle = "0.000000"
bogus_afterglow = "0.000000"
PR = "0.140000"
PG = "0.140000"
PB = "0.140000"
AS = "0.070000"
sat = "0.100000"
bogus_color = "0.000000"
TNTC = "0.000000"
LS = "32.000000"
LUTLOW = "12.000000"
LUTBR = "1.000000"
CP = "0.000000"
CS = "0.000000"
WP = "0.000000"
wp_saturation = "1.150000"
lsmooth = "0.750000"
GAMMA_INPUT = "2.400000"
bogus_interlacing = "0.000000"
inter = "325.000000"
interm = "4.000000"
inters = "0.000000"
iscan = "0.200000"
bogus_glow = "0.000000"
SIZEH = "25.000000"
SIGMA_H = "3.999997"
SIZEV = "1.000000"
SIGMA_V = "0.500000"
bogus_brightness = "0.000000"
glow = "0.010000"
bloom = "0.500000"
gamma_c = "1.000000"
brightboost = "3.999998"
brightboost1 = "1.999999"
bogus_scanline = "1.000000"
gsl = "0.000000"
scanline1 = "10.000000"
scanline2 = "5.000000"
beam_min = "1.999999"
beam_max = "0.850000"
beam_size = "0.700000"
vertmask = "0.500000"
scans = "0.600000"
spike = "1.000000"
bogus_filtering = "0.000000"
h_sharp = "5.200000"
s_sharp = "0.000000"
smart_ei = "0.000000"
ei_limit = "12.000000"
sth = "0.000000"
bogus_screen = "0.000000"
TATE = "0.000000"
IOS = "0.000000"
OS = "1.000000"
BLOOM = "0.000000"
csize = "0.000000"
bsize = "600.000000"
warpX = "0.000000"
warpY = "0.000000"
bogus_masks = "0.000000"
shadowMask = "7.000000"
maskstr = "0.000000"
masksize = "1.000000"
maskDark = "0.250000"
maskLight = "1.500000"
mcut = "2.000000"
mask_gamma = "3.499999"
slotmask = "0.800000"
slotwidth = "2.000000"
double_slot = "1.000000"
slotms = "1.000000"
mclip = "0.000000"
gamma_out = "2.400000"
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4"
SamplerLUT1 = "shaders_slang/crt/shaders/guest/lut/sony_trinitron1.png"
SamplerLUT1_linear = "true"
SamplerLUT1_wrap_mode = "clamp_to_border"
SamplerLUT1_mipmap = "false"
SamplerLUT2 = "shaders_slang/crt/shaders/guest/lut/sony_trinitron2.png"
SamplerLUT2_linear = "true"
SamplerLUT2_wrap_mode = "clamp_to_border"
SamplerLUT2_mipmap = "false"
SamplerLUT3 = "shaders_slang/crt/shaders/guest/lut/other1.png"
SamplerLUT3_linear = "true"
SamplerLUT3_wrap_mode = "clamp_to_border"
SamplerLUT3_mipmap = "false"
SamplerLUT4 = "shaders_slang/crt/shaders/guest/lut/custom_lut.png"
SamplerLUT4_linear = "true"
SamplerLUT4_wrap_mode = "clamp_to_border"
SamplerLUT4_mipmap = "false"
6 Likes

New Release Version (15.01.2021-r1):

Notable changes:

I added a deconvergence pass to the standard version. Started working on it a while ago, but since it sets an extra viewport size buffer i had some second thoughts about performance. The effect could eat away precise mask settings, but anyway…I mentioned this earlier, that adding complying effects gets increasingly harder, black level for example sounds easy, but is conflicting with afterglow etc. Nevertheless. Also fixed some scanline reference colors with hires/ntsc versions.

New Download link:

https://mega.nz/file/1hhFyQjZ#EVvqyDhIufa8HnSEGjCVtDghbKtCf_1fIKvQewDqmMU

Edit:

  • deconvergence effect balancing
  • a reasonable ammount of mask preservation added

Edit2:

  • small speedup, small bugfix
9 Likes

This is awesome news! I was hoping to add deconvergence to the Mega Bezel and this would be a perfect way :smile:

1 Like

That’s very nice to hear. :partying_face: I tweaked the shader a bit, i guess some annoyances can be nicely mitigated with the newer version. The main problem is that in a perfect case deconvergence should be implemented after scaling to output resolution and before masks, which also brings another set of circumstances.

2 Likes

Awesome work!!! Hires shader is perfect for me!!!

1 Like

Yeah I was thinking that might be the way.

I was wondering if the deconvergence and mask could be applied together in the extra pass, or if that’s not really possible because of how much the mask application is intertwined with the rest of the crt shader.

1 Like

There are coordinate conflicts with raster bloom, somewhat curvature, glow would get applied beyond the margins with curvature, also mask reference value and scanline strength are needed in the second (mask) pass and maybe other issues. Most probably solvable with doubling some code and parameters, but i don’t like doing this in general, especially at viewport resolution.

1 Like

Yeah this makes sense, more computation and of course copying code is kind of the last resort because of the difficulty with maintenance and possibility of extra bugs added.

1 Like

On a related note, I got the updated crt-guest-dr-venom (and crt-hyllian) shaders and presets integrated into my fork of the slang repo with a PR open to the main repo, if you want to take a look and make sure I didn’t screw anything up. (I can merge the PR into the main repo myself when the time comes, I just wanted to give it some review time first to hopefully spot any issues before merging)

I changed the presets to point to the existing stock and NTSC shaders to avoid duplicating code, moved the presets that incorporate multiple effects into the ‘presets’ directory and kept the basic and glow versions in the ‘crt’ directory.

I didn’t get rid of the original gdv version, but is there a reason to keep it out in the main crt directory vs archiving it?

4 Likes

That’s very nice. :smiling_face_with_three_hearts: The main difference between gdv1 and gdv2 is about 10-15% performance decrease of the newer version with vulkan, which seem to handle buffers faster. If the gdv1 preset could be moved into the crt/shaders/guest folder it would solve some sort of performance regresions for some users.

I would also like to ask if the deconvergence.slang could be updated with this version:

#version 450

/*
   CRT - Guest - Dr. Venom - Deconvergence pass
   
   Copyright (C) 2021 guest(r) - [email protected]
   
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 2
   of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   
*/

layout(push_constant) uniform Push
{
	vec4 OutputSize;
	uint FrameCount;
    float deconr;
    float decons;
	float cswitch;
} params;

#pragma parameter bogus_hdeconvergence "[ HORIZONTAL DECONVERGENCE ]: " 0.0 0.0 1.0 1.0
#pragma parameter deconr "          Hor. Deconvergence Color/Range" 0.0 -12.0 12.0 0.5
#define deconr        params.deconr     // Horizontal deconvergence colors range
#pragma parameter decons "          Horizontal Deconvergence Strength" 0.5 0.0 1.0 0.05
#define decons        params.decons     // Horizontal deconvergence colors strength
#pragma parameter cswitch "          Switch Deconvergence Colors" 1.0 -1.0 1.0 2.0
#define cswitch       params.cswitch    // Switch colors left/right

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;
}

#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 AvgLumPass;

#define COMPAT_TEXTURE(c,d) texture(c,d)

vec3 plant (vec3 tar, float r)
{
	float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
	return tar * r / t;
}

void main()
{
	
	vec3 color = COMPAT_TEXTURE(Source, vTexCoord).rgb;
	vec3 result = color;
	
	if (abs(deconr) > 0.5)
	{
		float step = cswitch/1920.0;
		
		vec2 dx = vec2(step, 0.0);
		
		float shift =  step * abs(deconr);
		vec4 coords = vec4(shift, -shift, 0.0, -0.5*shift);

		vec2 rc = coords.rb;
		vec2 gc = coords.gb;
		vec2 bc = coords.rb;
		
		if (deconr < -0.05) { rc = coords.rb; gc = coords.ab; bc = coords.gb; }
		
		float TATE = round(COMPAT_TEXTURE(Source, vec2(0.5)).a);

		if (TATE > 0.5)
		{ 
			rc = -rc.yx; gc = -gc.yx, bc = -bc.yx; dx = -dx.yx;
		}

		float r1 = COMPAT_TEXTURE(Source, vTexCoord +     rc).r;
		float g1 = COMPAT_TEXTURE(Source, vTexCoord +     gc).g;
		float b1 = COMPAT_TEXTURE(Source, vTexCoord +     bc).b;

		float r2 = COMPAT_TEXTURE(Source, vTexCoord + rc -dx).r;
		float g2 = COMPAT_TEXTURE(Source, vTexCoord + gc -dx).g;
		float b2 = COMPAT_TEXTURE(Source, vTexCoord + bc -dx).b;

		float r3 = COMPAT_TEXTURE(Source, vTexCoord + rc +dx).r;
		float g3 = COMPAT_TEXTURE(Source, vTexCoord + gc +dx).g;
		float b3 = COMPAT_TEXTURE(Source, vTexCoord + bc +dx).b;

		vec3 result1 = vec3(r1,g1,b1);
		vec3 result2 = vec3(r2,g2,b2);
		vec3 result3 = vec3(r3,g3,b3);
		
		result1 = mix(color, result1, decons);
		result2 = mix(color, result2, decons);
		result3 = mix(color, result3, decons);
		result = (result1+result2+result3)/3.0;
		result = plant(result, 0.5*(max(max(color.r,color.g),color.b)+max(max(result.r,result.g),result.b)));
	}
	
	FragColor = vec4(result, 1.0);
}

It’s newer and i think i finally resolved the RB issue (unreleased yet).

Otherwise the timing is very fine and i didn’t notice any other quirks.

Thanks again, @hunterk. :laughing:

5 Likes

Got it updated, thanks. And I’ll just leave gdv1 there for now and we can consider twilighting it sometime in the future.

5 Likes

New Release Version (16.01.2021-r1):

Notable changes:

  • I think something was still missing with lighting options, that’s why i decided to implement ‘halation’ to round up the middle ground between bloom and glow. I think a touch of it makes the setups more appealing.
  • bloom and halation recieved extra passes, so the range and character can be set independent from glow. Not implemented with hi-res and ntsc versions.

Download link:

https://mega.nz/file/J8wGyLDa#uxmpoEwEYv2xsvtw2_pormMc8ZMBAi58K1feBLM0gJc

Screenie:

9 Likes

Aren’t you happy we cry all the time, then you get to do cool shit like this XD

1 Like

Yeah, there is more than one doctor involved. :grin:

2 Likes

Thanks again @guest.r for continuing to hit it out of the park!!! :exploding_head:

3 Likes