I meant that as a CRT-Guest update to do this internally (Not literally, but as a general idea) so the crt mask will not be distorted, In other words make it kinda act like retroarch
Okay, so turns out I was being a dumbass (as always). Adding Aspect Ratio to the Guest shaders (or any shader) is easy. Please try this CRT-Guest-HD Aspect Ratio TEST.
See if MASK looks right for you too, and try to change both Resolution and AspectSize settings to random values to check if anything breaks.
Everything is working on my end -
can you make a test for ntsc one too please?
Oops! Did a hasty copy/paste mistake. Find and replace CGHD_S09
with NTSC_S14
.
so far so good! seems work fine! thanks!
and here was the 960 hack https://forums.libretro.com/uploads/default/original/3X/7/0/701aedbce0dcff35033df9945d004b3751907ba4.jpeg for comparisonboth has similar sharp which is similar to retroarch too
didnt test the borders in ntsc but it seems work fine in CRT-Guest-HD from my test before you post the ntsc update
Can you check if scanlines (and everything else) looks fine on your end, when you change Aspect_Y.
I have to get something 240p in this case but I will try to test them
Hey, so I’ve recently got into CRT shaders for emulation (specifically PCSX2), so this may be a dumb question, but what value do I need to put into the CRT Guest Resolution_Y and Resolution_X? From the screenshots shared here, it looked like Guest-Advanced would look fine with default settings, but when I try using it like that on PCSX2, the games gets so blurry I can barely read any UI text. I took some screenshots and made an Image Slider for comparison (between no shader, CRT Royale and CRT Guest): https://imgsli.com/Mzk3ODU1/1/2 I’m trying to find alternatives to Royale because it crushes black levels, in games like Rule of Rose (that are naturally darker), I can barely see a thing in some rooms. I’m also normally playing at the PS2’s native res, I just bumped it to 4x for the sake of clarity when taking the screenshots.
For reference, I use Guest-NTSC on Duckstation (it came with the emulator when I downloaded it), and the only settings I changed there were NTSC Resolution Scaling from 1 to 2 and High Resolution Scanlines from 0 to 1, and in Duckstation it looks gorgeous (example: https://imgur.com/a/qm6qaSh). I tried using Guest-NTSC on PCSX2 and changing those two settings as well, but it still looks awful. Can anyone help me configure it correctly? Really don’t want to depend on Royale.
By default my Guest ports scale to 320x240 and if I’m not wrong Royale for ReShade scales to the full buffer size (so, 1920x1080 in your case).
You can try the same 1920x1080 in Guest or 960x540 for a softer look. And if you want scalines at those high resolutions you can adjust Internal Resolution Y: 0.5 | Y-Dowsample to your liking.
That did the trick! I set it to 960x540 and then increased the internal resolution to 1.5 just so the scanlines were slightly more visible. Thank you so much, this is the closest a CRT shader came to looking like how I remember the TVs I played as a kid, haha (specifically the Guest-NTSC version).
Most CRT shaders I’ve ran into seem to be made with upscaling in mind (so games running several times their original resolution), but this one does a pretty great job at the PS2’s native res as well
@Rincewind could you update the Duckstation port to the latest version from guest.r / latest port from DevilSingh and then also push it to https://github.com/stenzek/emu-shaders?
Thank you for the port
Yeah, I’ll probably update it one day when I’ll personally need those updates. Just don’t count on it as I’m rather busy, but feel free to give it a shot
Hello. I’m very new to CRT shaders/filters, but I decided to give it a try because I’ve been seeing people achieve great results in a lot of pixel art games. I’m currently trying to make the CRT Guest Advanced shader work on Ninja Gaiden Ragebound, but I think there’s something I’m misunderstanding. I found out the game’s native resolution is 480x270, so that’s what I put into the Resolution X / Resolution Y settings in the shader’s Preprocessor Definitions settings. However, this results in some of the text and the HUD elements being extremely blurry, as can be seen here: https://postimg.cc/gallery/TPnxCXJ (the images were too large to upload directly).
The other settings are all at default, and I am playing on a 4K OLED TV. If someone can tell me what I’m doing wrong or what other settings I need to fiddle with, I would really appreciate it. Sorry if this is a stupid question. As I said, I’m a complete noob to this. This is my first time really trying to dip my toes into it.
…I wouldn’t say “extremely” blurry. I mean the text is almost perfectly readable, that is how it is supposed to be …I think. The only blurry texts I saw are the one at the bottom right on the main menu and the “Esc” next to “challenges”.
This is to be expected because, from what I understand, and from experience, most modern pixel art games are (of course) not really made CRTs or CRT filters in mind. And it doesn’t help that most people (average or casual gamers) think that retro games looked pixelated, while some others (not all) that know about CRTs think that the only thing they did to the games was “scanlines”, while being ignorant of all the other things different types of CRTs did (blending etc).
So while the developers might nail the pixel art, the in-game text is almost always in HD or at least not the same resolution as the pixel/background art, so while using a CRT filter might make the pixel art even more beautiful and smooth/unpixelated (if using NTSC shaders), the text is almost always going to be blurry/unreadable, with a few games being exceptions, and in my opinion, this game is one of them since the text is the same resolution as the pixel art.
An example of the aforementioned unreadable text issue, right now I am playing The Last Faith with CRT-Guest-NTSC. The pixel art’s resolution is 640x360 and looks amazing with the shader, but at the same time it makes the text completely unreadable (tried the other 2 shaders too). So I just switch the shader off during dialogue or inventory management etc, and turn it back on during normal gameplay, best compromise I say.
As for this game, to confirm, I just tested it with all Guest’s shaders with the default settings (for the sake of comparison) at 480x270, and so far all important texts are perfectly readable including cutscenes.
Which one did you use, the CRT-Guest-Advanced or CRT-Guest-HD. If you used advanced try using the HD one, in my testing it offers much clearer text out of the rest in this game while at the same time the art being less pixelated (smooth edges) compared to CRT-Guest-Advanced. Although completely irrelevant, I say NTSC shaders are the best for pixel art/retro games, with the phases & masks up to individual preference (my personal favorites are phase 2 & masks 1, 4 & especially 5 (2, 5 & 6 in reshade)).
Here are screenshots of this game using all three Guest shaders (at 1080p because that’s my max resolution). As for the NTSC screenshots, for some reason taking screenshots when using 2 phase would cause artifacts that are not present in-game/pre-screenshot, such as text being discolored and edges being pixelated, so I used mixed phase which doesn’t produce such artifacts, while the Advanced and HD ones use regular 2 phase.
Main Menu CRT-Guest-Advanced
Main Menu CRT-Guest-HD
Main Menu CRT-Guest-NTSC (Mixed Phase)
First Cutscene CRT-Guest-Advanced
First Cutscene CRT-Guest-HD
First Cutscene CRT-Guest-NTSC (Mixed Phase)
As stated, the text is perfectly readable, even in NTSC. But if it is a bother for you, open reshade, go to settings, in the “Effect toggle key” field use whatever key you want. Now just toggle the shader off when reading any text and turn it back on.
Hey there! I dont know if its only me, but all your images are only showing “Upgrade to premium”.
For SVGA content with Guest-Advanced you may want to keep the resolution setting to 1080p or what you’re using, and try setting the “high resolution scanline” parameter to 1, and tweak the “Internal Resolution-Y multiplier” to your liking. If you use NTSC you may also try to bump the “NTSC resolution” parameter up. That may help with reading small fonts.
I’m playing through Fallout 2 with a mix of scalers and Guest’s shader and I dont have trouble reading a lot with it from the couch. That being said the high contrast green font also helps tho, and there’s a lot of modern games I’d try a bigger font mod with. Might be mutating into a molerat someday. XD
Hey, @Pluuth and @AliAkbar. You can use my CRT-Geom port to get perfect scanlines in Ragebound (Just set Resolution_Y to 540 not 270) -
uniform float gm_crt <
ui_type = "drag";
ui_min = 0.5;
ui_max = 4.0;
ui_step = 0.05;
ui_label = "CRT Gamma";
> = 2.4;
uniform float gm_lcd <
ui_type = "drag";
ui_min = 0.5;
ui_max = 4.0;
ui_step = 0.05;
ui_label = "LCD Gamma";
> = 2.2;
uniform float brightness <
ui_type = "drag";
ui_min = 0.25;
ui_max = 5.0;
ui_step = 0.01;
ui_label = "Brightness";
> = 1.0;
uniform float dmw <
ui_type = "drag";
ui_min = 0.0;
ui_max = 1.0;
ui_step = 0.05;
ui_label = "Mask Strength";
> = 0.3;
uniform float wib <
ui_type = "drag";
ui_min = 0.1;
ui_max = 0.5;
ui_step = 0.05;
ui_label = "Scanlines Strength";
> = 0.3;
uniform float gauss_scanlines <
ui_type = "drag";
ui_min = 0.0;
ui_max = 1.0;
ui_step = 1.0;
ui_label = "Gaussian Scanlines";
> = 0.0;
uniform float csize <
ui_type = "drag";
ui_min = 0.0;
ui_max = 0.25;
ui_step = 0.005;
ui_label = "Corner Size";
> = 0.0;
uniform float bsize <
ui_type = "drag";
ui_min = 0.0;
ui_max = 3.0;
ui_step = 0.01;
ui_label = "Border Size";
> = 0.01;
uniform float sborder <
ui_type = "drag";
ui_min = 0.25;
ui_max = 2.0;
ui_step = 0.05;
ui_label = "Border Intensity";
> = 0.75;
uniform float warpx <
ui_type = "drag";
ui_min = 0.0;
ui_max = 0.25;
ui_step = 0.01;
ui_label = "Curvature X (Default 0.03)";
> = 0.0;
uniform float warpy <
ui_type = "drag";
ui_min = 0.0;
ui_max = 0.25;
ui_step = 0.01;
ui_label = "Curvature Y (Default 0.04)";
> = 0.0;
uniform float c_shape <
ui_type = "drag";
ui_min = 0.05;
ui_max = 0.6;
ui_step = 0.05;
ui_label = "Curvature Shape";
> = 0.25;
#include "ReShade.fxh"
#define TexSize float2(Resolution_X,Resolution_Y)
#define IptSize float2(Resolution_X,Resolution_Y)
#define OptSize float4(BUFFER_SCREEN_SIZE,1.0/BUFFER_SCREEN_SIZE)
#define SrcSize float4(TexSize,1.0/TexSize)
#define aspect float2(1.0,0.75)
#define FIX(c) max(abs(c),1e-5)
#define PI 3.14159265
#define mod_fact texcoord.x*TexSize.x*OptSize.x/IptSize.x
#define TEX2D(c) tex2D(GEOM_S00,(c))
#ifndef Resolution_X
#define Resolution_X 320
#endif
#ifndef Resolution_Y
#define Resolution_Y 240
#endif
#define GEOM_S00 ReShade::BackBuffer
uniform int framecount<source="framecount";>;
float2 curve(float2 pos)
{
pos=pos*2.0-1.0;
pos=lerp(pos,float2(pos.x*rsqrt(1.0-c_shape*pos.y*pos.y),pos.y*rsqrt(1.0-c_shape*pos.x*pos.x)),float2(warpx,warpy)/c_shape);
return pos*0.5+0.5;
}
float corner(float2 pos)
{
float2 bc=bsize*float2(1.0,OptSize.x/OptSize.y)*0.050;
pos=clamp(pos,0.0,1.0);
pos=abs(2.0*(pos-0.5));
float csz=lerp(400.0,7.0,pow(4.0*csize,0.10));
float crn=dot(pow(pos,csz.xx*float2(1.0,OptSize.y/OptSize.x)),1.0.xx);
crn=(csize==0.0)? max(pos.x,pos.y):pow(crn,1.0/(csz));
pos=max(pos,crn);
float2 rs=(bsize==0.0)? 1.0.xx:lerp(0.0.xx,1.0.xx,smoothstep(1.0.xx,1.0.xx-bc,sqrt(pos)));
rs=pow(rs, sborder.xx);
return sqrt(rs.x*rs.y);
}
float mod(float x,float y)
{
return x-y* floor(x/y);
}
float4 scanlines(float distance,float4 color)
{
if(gauss_scanlines==1.0)
{
float4 wid=0.3+0.1*pow(color,3.0);
float4 wld=distance/wid;
return 0.4*exp(-wld*wld)/wid;}else
{
float4 wid=2.0+2.0*pow(color,4.0);
float4 wld=distance/wib;
return 1.4*exp(-pow(wld*rsqrt(0.5*wid),wid))/(0.6+0.2*wid);
}
}
float4 GeomPS(float4 position:SV_Position,float2 texcoord:TEXCOORD):SV_Target
{
float2 ilfac=float2(1.0,clamp(floor(IptSize.y/200.0),1.0,2.0));
float2 xy=curve(texcoord);
float2 ilvec=float2(0.0,0.0>1.5?mod(framecount,2.0):0.0);
float2 ratio_scale=(xy*TexSize-0.5+ilvec)/ilfac;
float2 uv_ratio=frac(ratio_scale);
float2 cone=ilfac/TexSize;
float2 yx=xy;
float cval=corner(xy);
float clear=fwidth(ratio_scale.y);
xy=(floor(ratio_scale)*ilfac+0.5-ilvec)/TexSize;
float4 co=PI*float4(1.0+uv_ratio.x,uv_ratio.x,1.0-uv_ratio.x,2.0-uv_ratio.x);
co =FIX(co);
co =2.0*sin(co)*sin(co/2.0)/(co*co);
co/=dot(co,1.0);
float4 col0=clamp(TEX2D(xy+float2(-cone.x,cone.y))*co.x+TEX2D(xy+float2(0.0,cone.y))*co.y+TEX2D(xy+cone)*co.z+TEX2D(xy+float2(2.0*cone.x,cone.y))*co.w,0.0,1.0);
float4 col1=clamp(TEX2D(xy+float2(-cone.x,0.0))*co.x+TEX2D(xy)*co.y+TEX2D(xy+float2(cone.x,0.0))*co.z+TEX2D(xy+float2(2.0*cone.x,0.0))*co.w,0.0,1.0);
col0=pow(col0,gm_crt);
col1=pow(col1,gm_crt);
float4 weights0=scanlines(1.0-uv_ratio.y,col0);
float4 weights1=scanlines( uv_ratio.y,col1);
uv_ratio.y=uv_ratio.y+1.0/3.0*clear;
weights0=(weights0+scanlines(abs(1.0-uv_ratio.y),col0))/3.0;
weights1=(weights1+scanlines(abs( uv_ratio.y),col1))/3.0;
uv_ratio.y=uv_ratio.y-2.0/3.0*clear;
weights0=(weights0+scanlines(abs(1.0-uv_ratio.y),col0))/3.0;
weights1=(weights1+scanlines(abs( uv_ratio.y),col1))/3.0;
float3 mul_res=(col1*weights1+col0*weights0).rgb;
float3 maskweights=lerp(float3(1.0,1.0-dmw,1.0),float3(1.0-dmw,1.0,1.0-dmw),floor(mod(mod_fact,2.0)));
mul_res*=maskweights;
mul_res=pow(mul_res,1.0/gm_lcd);
return float4(mul_res*brightness*cval,1.0);
}
technique CRT_Geom
{
pass
{
VertexShader=PostProcessVS;
PixelShader=GeomPS;
}
}
Resolution_Y = 270 -
Resolution_Y = 540 -
If you want something similar in the Guest-Advanced shaders. You need to ask @guest.r for EVEN/ODD scanlines.
isnt that what interlaced mode=1-3 do?