Experimentation with a glowing CRT shader

Yeah that’s because that bush is a bit brighter and the glow inside of it makes that happen. Same on the red letters and on the mountains in the background (this one is easier to spot in motion).

I made that hypothesis above to tone down the glow inside of an already light part of the original picture but I have no idea if that’s a valid approach in shader language.

The CRT geom scanline beam has variable width depending on intensity.

That’s true but it gets a bit extreme here with this level of brightness + glow. And there is something else going on: try watching super mario world intro with BLOOM_ONLY 1 in resolve.cg (snes9xnext crtglow_lanczos.cgp).

That’s true but it gets a bit extreme here with this level of brightness + glow. And there is something else going on: try watching super mario world intro with BLOOM_ONLY 1 in resolve.cg (snes9xnext crtglow_lanczos.cgp).[/quote]

Pretty soon you will be able to modify params exactly to your liking though, so it’s not a real concern.

good job using the new feature. when I tried to implement bloom for hyllians crt shader a mipmapping feature was missing so I had to use big kernels with still too small effect. this makes it of course way easier and performant, nicely done!

Hi Maister,

I’m looking at your cgps and can’t understand how you scale using gauss or lanczos in horiz and vert at ONLY 1x scale and don’t screw the scanlines??? I’m really lost on how this mipmap feature works.

And then, after that, you scale using blur at 0.25 scale?? what did you say? 0.25?? Explain the magic, please.

The horizontal gauss is 1x scale horizontally relative to viewport and 1x relative to source. The vertical pass scales to 1x viewport relative for both dimensions (which only scales it vertically). scale_type_x and scale_type_y allows you to set how the scaling works for dimensions individually.

For 0.25 scale, the whole point is that the blurring pass happens at a lower resolution than the full screen. By mipmapping the threshold pass, I already have a threshold pass which is 0.25 scale (2nd miplevel) and I can blur on that directly. In the final pass I simply composite the low-res blur over the full-res CRT output.

Here’s the message I get when trying to load ‘crtglow_gauss.cgp’ with RetroArch 1.0.0.2 (is that “not recent” enough ?) :

RetroArch [ERROR] :: Cannot find "shaders" param.
RetroArch [ERROR] :: Failed to parse CGP file.
RetroArch [WARN] :: [GL]: Failed to set multipass shader. Falling back to stock.

RetroArch [ERROR] :: Setting RGUI CGP failed.

That should not possibly happen. Your crtglow_gauss.cgp is likely just broken.

Lol I get it. That’s because I had downloaded all the shader files one by one, by right clicking ‘Save As…’ It adds uneeded html markup to the .cgp file :confused:

Omg I love how it looks ! Probably a bit too glowy/blurry though, but I lçvoe it

Comparison between crt-cgwg and crtglow_gauss :

SM http://screenshotcomparison.com/comparison/77121

Zelda http://screenshotcomparison.com/comparison/77131

For reference : crt-cgwg crtglow_gauss crt-hyllian

I still like cgwg scanlines a bit more because the scanlines are not only horizontal but vertical. They seem a little bit more accurate to me, I don’t know why, thats subjective off course

EDIT : yea, crt-cgwg is still king imo. Why not add glow/bloom to crt-cgwg and be done with it

The vertical lines are just a faux dotmask. You can added it any shader with just a couple of lines copied from cgwg’s CRT shader. Here’s a separate shader pass that will do it (also just added it to the common-shaders repo):

/* COMPATIBILITY 
   - HLSL compilers
   - Cg   compilers
*/

/*
   Dot Mask
   Author: cgwg
   License: GPL
   
   Note: This shader is just the dotmask code from cgwg's CRT shader.
*/

struct input
{
   float2 video_size;
   float2 texture_size;
   float2 output_size;
   float  frame_count;
   float  frame_direction;
   float frame_rotation;
   sampler2D texture : TEXUNIT0;
};

void main_vertex
(
   float4 position : POSITION,
   out float4 oPosition : POSITION,
   uniform float4x4 modelViewProj,

   float4 color : COLOR,
   out float4 oColor : COLOR,

   float2 texCoord : TEXCOORD,
   out float2 oTexCoord : TEXCOORD,

   uniform input IN
)
{
   oPosition = mul(modelViewProj, position);
   oColor = color;
   oTexCoord = texCoord;
}

#define mod_factor texCoord.x * IN.texture_size.x * IN.output_size.x / IN.video_size.x

float4 main_fragment (in float2 texCoord : TEXCOORD, uniform input IN) : COLOR
{
   float3 res = tex2D(IN.texture, texCoord);
   
   // dot-mask emulation:
   // Output pixels are alternately tinted green and magenta.
   float3 dotMaskWeights = lerp(
                           float3(1.0, 0.7, 1.0),
                           float3(0.7, 1.0, 0.7),
                           floor(fmod(mod_factor, 2.0))
						   );
   res *= dotMaskWeights;

      return float4(res, 1.0);
}

And in crt-hyllian you can enable it by uncommenting the PHOSPHOR option inside the shader.

I disabled it in the glow version because I though a clean image would be better. But, it’s there to your taste.

Added an NTSC + crt-glow preset (8 shader passes :V). Surprisingly enough runs fullspeed on my puny HD3000 at reduced resolutions.

Thanks for your replies guys

I’d love to try the ntsc preset Maister but I’m getting a blank screen with scanlines when loading it. So I tried to load again the ‘crtglow_gauss.cgp’ preset and now I’m getting this :

I tried to redownload the entire shaders repository and make sure everything was configured properly but it’s just the same :confused:

EDIT : yup ok, something is wrong in the new ‘resolve.cg’. Reverting it back to the previous version solved the above weird colour issue for me EDIT : … but I still get a blank screen with the new ntsc preset :confused:

Maister, I have an idea for the threshold part of the glowing algorithm. Instead a hard decision on which parts will glow or not, why not glow everything but with different weights depending on intensity? I made this in threshold.cg:


#define BLOOM_STRENGTH 0.5


float4 main_fragment(float2 tex : TEXCOORD0, uniform sampler2D s0 : TEXUNIT0, uniform input IN) : COLOR
{
   float3 color = 1.0 * tex2D(s0, tex).rgb;
//   return float4(saturate(OVERDRIVE * (color - THRESHOLD)), 1.0);
   return float4(color * color * BLOOM_STRENGTH, 1.0);
}

The glow decay with the square of the color intensity. Some games have some animations where the intensity varies in time (see Super Nova logo screen, for example). In these games, hard decision makes the glowing disappear instantly. With a varying glow, it vanishes smoothly.

Or even use the cube to decay faster, but not instantly: color * color * color.

Are you using intel video? maybe clarkdale? I have a similar issue

I changed to PASSPREV to work with NTSC shader as well (shader pass alias support is even more recent :p). You need an updated build to be able to use it since I recently fixed a critical bug with PASSPREV shader support.

EDIT: Looking at that image, it’s definitely the PASSPREV bug I had when developing crt-glow. Get an updated build and it should work just fine.

Hyllian: Yes, I’ve tried doing something like that before but it didn’t always turn out great. Maybe I can add back the pow() based approach now, since there have been lots of changes since then. And we have shader parameters to fine-tweak.

Yup I downloaded a very recent RetroArch build (maybe you should sticky this in the OP) and now it works fine

This shader was very dark to begin with, I tweaked it a bit and got the next, I share the files with my settings.

-Dilation was set to 0.0, by some reason the pixels are already too fat. -Sharpness was deleted. -Output gamma set to 3.0 (brighter image) -Glow was more subtle and spread. -Blue tint was adjusted. -Among other things that I had already don on crt-hyllian.

enjoy!

raw…crt-hyllian…crt-hyllilan+bloom (hunterk’s).crt-glow (default)…crt-glow (tweaked)

Here’s the zip with the modifications.