Skip to content

CRT Shader Alternative (Speed, Simplicity) #636

@torridgristle

Description

@torridgristle

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.

Activity

changed the title [-]CRT Shader Alternative (Speed, Simplicity)[/-] [+]CRT Shader Alternative (Speed, Simplicity) + Shader Config Corruption[/+] on Jul 20, 2018
changed the title [-]CRT Shader Alternative (Speed, Simplicity) + Shader Config Corruption[/-] [+]CRT Shader Alternative (Speed, Simplicity)[/+] on Jul 23, 2018
cuu

cuu commented on Feb 27, 2019

@cuu
Contributor

any example source?

torridgristle

torridgristle commented on Mar 1, 2019

@torridgristle
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);

}

added a commit that references this issue on Nov 9, 2020
nesbox

nesbox commented on Nov 9, 2020

@nesbox
Owner

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.

self-assigned this
on Nov 9, 2020
added a commit that references this issue on Nov 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @cuu@nesbox@torridgristle

      Issue actions

        CRT Shader Alternative (Speed, Simplicity) · Issue #636 · nesbox/TIC-80