I’ve normalized the brightness in gauss and lanczos. A BOOST value of 1.0 should be the same now. There’s also a BOOST value centered about 1.0 now in gauss_vert.cg. I’ve added a path for crt-geom-style scanlines. In blur_params.inc, you can now tweak how wide the glow blur should be.
Thanks for your work.
I don’t really understand the CRT_GEOM_BEAM switch. Putting 0 just makes everything crazy bright…?
Maister, I have two questions:
1- How do you use the new mipmap feature? Is it enabled only through cgp file?
2- I don’t know if it’s a bug in the texture lookup or a driver problem: I tested the latest crt-glow and when I set integer scaling and custom aspect ratio, if I use an odd scaling like 5x5 or 3x3, many artifacts appear in the left side of the image. At 4x4 or other even scaling factors, the screen is ok.
The artifacts at 3x3:
BTW: I like how the bloom glows in Super Punch Out nintendo’s logo! It glows like the lights in a stadium, very cool! It’s the only bloom that shows that way. I’d like to know how it is in a real crt.
The lanczos version is much nicer after those tweaks; I definitely prefer it now for the reduced blur.
Out of curiosity, could a similar technique be applied to the lcd-shader to brighten it up, or is that just too different? I’d love something as bright as this for handhelds.
This approach is likely to work with most shaders. As long as the shader is aware that it can output data in say, [0, 1.15] range. (Divide by 1.15 to pack that in [0, 1]).
Hyllian: You set mipmap_inputN in the cgp. If say mipmap_input0 = true, then the input texture from the game is mipmapped. If mipmap_inputN = true, then the input to shaderN is mipmapped (so the pass before that shader is mipmapped). As for that image you’re most likely hitting a case where most texels are sampled at texel boundary … Are you using square pixel ratio? I really wish there was a good way to sample nearest without risking these issues.
In this crt glow, are you using mimmap and sRGB? I just can’t understand what these features are doing in this glow combination. Specifically in which pass.
I’m using integer scaling ON, so I’m sure the pixel is square.
And there is! Though a bit slower. See my implementation in jinc2.cg inside windowed folder. It works the same way in nearest and linear! I think I’ll change other shaders to that approach. The idea is just to calculate the texture sample coordinates in fragment (since in vertex isn’t reliable) pointing exactly to the center of the texel (and it’s only possible in fragment).
You still have to round with frac() though. E.g. frac() with 1.0 +/- epsilon can get a bit hairy. Still, guess it’s a bit more reliable to manually center the texture sample (might as well have used texelFetch with integer coordinates). More modern GLSL has textureOffset() and texelFetchOffset() which is nice for these things at least. :v
The ideal case would be a hypothetical texelQuery() where you give it the texture coord and level, and it’d return the texel coordinate (integer) it would fetch with nearest as well as the [0.0, 1.0] sampling point within that texel. Then you could just texelFetchOffset() on that and use the [0.0, 1.0] sampling point offset to compute filter kernels.
As for mipmapping, the CRT output gets fed to a threshold shader which lets only the very brightest regions pass through. This threshold output gets mipmapped. Then two blur passes work on miplevel 2 of the threshold output to smear it out really good (glow component). It’s a separable 9x9 blur, which corresponds to a 36x36 blur at full resolution, but ofc, way, way faster due to smaller filter kernel and lower FBO resolution. Then in resolve pass the CRT output gets added along with the smeared out “glow”.
sRGB framebuffers are used so I can work in linear space without crushing black regions due to gamma and without having to do constant pow(gamma), pow(1.0 / gamma) all the time.
Really liking this shader…
http://www.myspacegens.com/animated_gif … 848891.gif
But would love an script option to alter the sharpness, so i can sharpen the image up a tad more
I don’t like gif to show several pics, can’t stop and examine anything. That’s OK for direct comparison between 2 pictures but no more.
My feeling with this shader is that it’s really nice when displaying some sprites above a dark background, the glow really benefits from this scenario and is striking. Then when everything is brighter that’s where it’s turning bad: it’s overly bright and a bit blurry, eating over the scanlines that become irregular.
I wonder if it’s possible to do something about that. Like keeping the glow in check when it’s over an already bright portion of the picture (ex: a white ball would get the 100% glow on the external border of the ball, but something like 50% inside = any value that doesn’t mess the scanlines).
Yes that’s better.
As your pics are high res we can really see the issue with scanlines, and we can zoom in. Particularly on Mario World screen (evident on the bushes), super star wars, twinbee or wild guns.
So how do we fix this then =D
EDIT: Hmmm looking at that Mario World title screen picture if you view it full screen,
http://i3.minus.com/iqtnhh8EKnCHU.jpg
then the scanlines on the bush on the right looks ok, but the bush in the centre the scanline are almost ‘bleed’ out, that seem a bit odd!??
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.