Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRT Shader Alternative (Speed, Simplicity) #636

Closed
torridgristle opened this issue Jul 16, 2018 · 3 comments
Closed

CRT Shader Alternative (Speed, Simplicity) #636

torridgristle opened this issue Jul 16, 2018 · 3 comments
Assignees

Comments

@torridgristle
Copy link

torridgristle commented Jul 16, 2018

tl;dr individual x and y integer scaling followed by bilinear / fast bicubic / fast gaussian / Mitchell-Netravali cubic / Hyllian cubic scaling options.

Went through the function keys and noticed there's a CRT shader in the dev build. Conceptually I'm all for it, but it looks awful. A faster, less resource intensive, and less visually jarring alternative would be to toggle bilinear filtering for a softer appearance.

Ideally it'd be like 2x or 3x (configurable perhaps for big screens) nearest neighbor upscaling and then bilinear the rest, and maybe an option to control which axis is interpolated and how like in Mednafen where you can specify to only use bilinear, or really linear at this point, interpolation on the X axis for example and then nearest neighbor upscaling on the Y axis followed by bilinear, so that the blocky vertical scaling softens up a tad without needless blurring via shaders. Plus it could fill resolutions that aren't integer scales of 240 x 136.

After even 3x nearest neighbor, filling it out to 1600x900 with bilinear doesn't really look blurry at all, just subtly soft. 2x nearest neighbor then bilinear to 1600x900 however, I'd consider that blurry. 2x horizontal, 3x vertical, bilinear the rest is somewhere between, and 1x horizontal 3x vertical visually feels like the stereotypical overpowered nostalgia shader blur while not being too awful to look at, I don't think I like it very much though.

Update: I compiled a version with linear GPU filtering and it looks awful on the edges, however Inigo Quilez's shader for improved texture interpolation looks pretty good, and so does nearest then bilinear but I haven't gotten to that yet.

bilinear
quilez

I think it looks alright, visually just about the same as 2x nearest then 2x bilinear. Maybe a little better but I'm not sure it really is.

Since the bitmap cursor is on a different layer it looks really bad on the edges unfortunately, but I imagine with pixel_perfect enabled for the cursor it could be added to the low-res image what gets scaled up rather than being overlaid on top of it for both pixel_perfect disabled and enabled.

@torridgristle torridgristle changed the title CRT Shader Alternative (Speed, Simplicity) CRT Shader Alternative (Speed, Simplicity) + Shader Config Corruption Jul 19, 2018
@torridgristle torridgristle changed the title CRT Shader Alternative (Speed, Simplicity) + Shader Config Corruption CRT Shader Alternative (Speed, Simplicity) Jul 22, 2018
@cuu
Copy link
Contributor

cuu commented Feb 27, 2019

any example source?

@torridgristle
Copy link
Author

I've got a shader I've written for Quark that's nicely optimized. It works by recalculating any values between integer pixel coordinates and should be easy to rework to the variables TIC-80 uses, which I no longer remember.

#version 150

uniform sampler2D source[];
uniform vec4 sourceSize[];

in Vertex { vec2 texCoord; };
out vec4 fragColor;

void main()
{
vec2 SStep = texCoord * sourceSize[0].xy + 0.5;
vec2 SStepInt = floor(SStep);
vec2 SStepFra = SStep - SStepInt;

SStep = ((SStepFra * SStepFra * SStepFra * (SStepFra * (SStepFra * 6 - 15) + 10)) + SStepInt - 0.5) * sourceSize[0].zw;

fragColor = texture(source[0], SStep);

}

@nesbox
Copy link
Owner

nesbox commented Nov 9, 2020

I moved vertex shader definition (with #version) to the config and divided it into two parts (vertex/pixel).
Now you can write any shader you want.

...
CRT_SHADER=
{
	VERTEX=[[
		#version 110
		attribute vec3 gpu_Vertex;
		attribute vec2 gpu_TexCoord;
		attribute vec4 gpu_Color;
		uniform mat4 gpu_ModelViewProjectionMatrix;
		varying vec4 color;
		varying vec2 texCoord;
		void main(void)
		{
			color = gpu_Color;
			texCoord = vec2(gpu_TexCoord);
			gl_Position = gpu_ModelViewProjectionMatrix * vec4(gpu_Vertex, 1.0);
		};
	]],
	PIXEL=[[
		#version 110
		varying vec2 texCoord;
		uniform sampler2D source;
		uniform float trg_x;
		uniform float trg_y;
		uniform float trg_w;
		uniform float trg_h;
		uniform float scr_w;
		uniform float scr_h;

		...
	]]
}

Thank you.

@nesbox nesbox closed this as completed Nov 9, 2020
@nesbox nesbox self-assigned this Nov 9, 2020
nesbox added a commit that referenced this issue Nov 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants