New CRT shader from Guest + CRT Guest Advanced updates

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

Messing around I found this amusing effect of giving darker games a depth of field effect with, Halation Strength 0.5 and Gamma correct 0.5.

5 Likes

Awesome, I noticed hard edges when trying to make my monochrome green preset. Now it’s time to rebuild. :+1:

1 Like

What is “Bloom” and what is “Halation” can these be seen on real CRTs?

Edit: google comes up with references from photographers saying halation is a form of light spreading around mostly brighter objects? Is this also how halation should be interpreted for CRT?

So

  • Glow = spreading of light around all objects
  • Halation = spreading of light around bright objects?
  • Bloom = ?

Bloom and halation are related with masks. And welding. :woozy_face:

1 Like

New Release Version (17.01.2021-r1):

Notable changes:

I worked a bit more with the halation effect and now saturation and contrast are greatly improved. It can be very nice to use with stronger masks, or without masks…

Download link:

https://mega.nz/file/MtBXzYCB#q5-_aU-MbQ2_mxZbbmghLWVX0qtO6y9-9DvBBOoDOWs

5 Likes