Fix rounding errors in the LCD and CRT shaders, closes #595

This commit is contained in:
Lior Halphon
2024-03-09 18:07:04 +02:00
parent a125da6a98
commit 5e2b6e7e9e
3 changed files with 44 additions and 44 deletions

View File

@@ -23,22 +23,22 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
/* Setting up common vars */ /* Setting up common vars */
vec2 pos = fract(position * input_resolution); vec2 pos = fract(position * input_resolution);
vec2 sub_pos = fract(position * input_resolution * 6); vec2 sub_pos = pos * 6;
vec4 center = texture_relative(image, position, vec2(0, 0)); vec4 center = texture_relative(image, position, vec2(0, 0));
vec4 left = texture_relative(image, position, vec2(-1, 0)); vec4 left = texture_relative(image, position, vec2(-1, 0));
vec4 right = texture_relative(image, position, vec2(1, 0)); vec4 right = texture_relative(image, position, vec2(1, 0));
/* Vertical blurring */ /* Vertical blurring */
if (pos.y < 1.0 / 6.0) { if (sub_pos.y < 1.0) {
center = mix(center, texture_relative(image, position, vec2( 0, -1)), 0.5 - sub_pos.y / 2.0); center = mix(center, texture_relative(image, position, vec2( 0, -1)), 0.5 - sub_pos.y / 2.0);
left = mix(left, texture_relative(image, position, vec2(-1, -1)), 0.5 - sub_pos.y / 2.0); left = mix(left, texture_relative(image, position, vec2(-1, -1)), 0.5 - sub_pos.y / 2.0);
right = mix(right, texture_relative(image, position, vec2( 1, -1)), 0.5 - sub_pos.y / 2.0); right = mix(right, texture_relative(image, position, vec2( 1, -1)), 0.5 - sub_pos.y / 2.0);
} }
else if (pos.y > 5.0 / 6.0) { else if (sub_pos.y > 5.0) {
center = mix(center, texture_relative(image, position, vec2( 0, 1)), sub_pos.y / 2.0); center = mix(center, texture_relative(image, position, vec2( 0, 1)), (sub_pos.y - 5) / 2.0);
left = mix(left, texture_relative(image, position, vec2(-1, 1)), sub_pos.y / 2.0); left = mix(left, texture_relative(image, position, vec2(-1, 1)), (sub_pos.y - 5) / 2.0);
right = mix(right, texture_relative(image, position, vec2( 1, 1)), sub_pos.y / 2.0); right = mix(right, texture_relative(image, position, vec2( 1, 1)), (sub_pos.y - 5) / 2.0);
} }
/* Scanlines */ /* Scanlines */
@@ -75,7 +75,7 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
} }
/* Blur the edges of the separators of adjacent columns */ /* Blur the edges of the separators of adjacent columns */
if (pos.x < 1.0 / 6.0 || pos.x > 5.0 / 6.0) { if (sub_pos.x < 1.0 || sub_pos.x > 5.0) {
pos.y += 0.5; pos.y += 0.5;
pos.y = fract(pos.y); pos.y = fract(pos.y);
@@ -112,35 +112,35 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
vec4 midright = mix(right, center, 0.5); vec4 midright = mix(right, center, 0.5);
vec4 ret; vec4 ret;
if (pos.x < 1.0 / 6.0) { if (sub_pos.x < 1.0) {
ret = mix(vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_HIGH * left.b, 1), ret = mix(vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_HIGH * left.b, 1),
vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_LOW * left.b, 1), vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_LOW * left.b, 1),
sub_pos.x); sub_pos.x);
} }
else if (pos.x < 2.0 / 6.0) { else if (sub_pos.x < 2.0) {
ret = mix(vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_LOW * left.b, 1), ret = mix(vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_LOW * left.b, 1),
vec4(COLOR_HIGH * center.r, COLOR_HIGH * center.g, COLOR_LOW * midleft.b, 1), vec4(COLOR_HIGH * center.r, COLOR_HIGH * center.g, COLOR_LOW * midleft.b, 1),
sub_pos.x); sub_pos.x - 1);
} }
else if (pos.x < 3.0 / 6.0) { else if (sub_pos.x < 3.0) {
ret = mix(vec4(COLOR_HIGH * center.r , COLOR_HIGH * center.g, COLOR_LOW * midleft.b, 1), ret = mix(vec4(COLOR_HIGH * center.r , COLOR_HIGH * center.g, COLOR_LOW * midleft.b, 1),
vec4(COLOR_LOW * midright.r, COLOR_HIGH * center.g, COLOR_LOW * center.b, 1), vec4(COLOR_LOW * midright.r, COLOR_HIGH * center.g, COLOR_LOW * center.b, 1),
sub_pos.x); sub_pos.x - 2);
} }
else if (pos.x < 4.0 / 6.0) { else if (sub_pos.x < 4.0) {
ret = mix(vec4(COLOR_LOW * midright.r, COLOR_HIGH * center.g , COLOR_LOW * center.b, 1), ret = mix(vec4(COLOR_LOW * midright.r, COLOR_HIGH * center.g , COLOR_LOW * center.b, 1),
vec4(COLOR_LOW * right.r , COLOR_HIGH * center.g, COLOR_HIGH * center.b, 1), vec4(COLOR_LOW * right.r , COLOR_HIGH * center.g, COLOR_HIGH * center.b, 1),
sub_pos.x); sub_pos.x - 3);
} }
else if (pos.x < 5.0 / 6.0) { else if (sub_pos.x < 5.0) {
ret = mix(vec4(COLOR_LOW * right.r, COLOR_HIGH * center.g , COLOR_HIGH * center.b, 1), ret = mix(vec4(COLOR_LOW * right.r, COLOR_HIGH * center.g , COLOR_HIGH * center.b, 1),
vec4(COLOR_LOW * right.r, COLOR_LOW * midright.g, COLOR_HIGH * center.b, 1), vec4(COLOR_LOW * right.r, COLOR_LOW * midright.g, COLOR_HIGH * center.b, 1),
sub_pos.x); sub_pos.x - 4);
} }
else { else {
ret = mix(vec4(COLOR_LOW * right.r, COLOR_LOW * midright.g, COLOR_HIGH * center.b, 1), ret = mix(vec4(COLOR_LOW * right.r, COLOR_LOW * midright.g, COLOR_HIGH * center.b, 1),
vec4(COLOR_HIGH * right.r, COLOR_LOW * right.g , COLOR_HIGH * center.b, 1), vec4(COLOR_HIGH * right.r, COLOR_LOW * right.g , COLOR_HIGH * center.b, 1),
sub_pos.x); sub_pos.x - 5);
} }
/* Anti alias the curve */ /* Anti alias the curve */

View File

@@ -5,13 +5,13 @@
STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution) STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
{ {
vec2 pos = fract(position * input_resolution); vec2 pos = fract(position * input_resolution);
vec2 sub_pos = fract(position * input_resolution * 6); vec2 sub_pos = pos * 6;
vec4 center = texture_relative(image, position, vec2(0, 0)); vec4 center = texture_relative(image, position, vec2(0, 0));
vec4 left = texture_relative(image, position, vec2(-1, 0)); vec4 left = texture_relative(image, position, vec2(-1, 0));
vec4 right = texture_relative(image, position, vec2(1, 0)); vec4 right = texture_relative(image, position, vec2(1, 0));
if (pos.y < 1.0 / 6.0) { if (sub_pos.y < 1.0) {
center = mix(center, texture_relative(image, position, vec2( 0, -1)), 0.5 - sub_pos.y / 2.0); center = mix(center, texture_relative(image, position, vec2( 0, -1)), 0.5 - sub_pos.y / 2.0);
left = mix(left, texture_relative(image, position, vec2(-1, -1)), 0.5 - sub_pos.y / 2.0); left = mix(left, texture_relative(image, position, vec2(-1, -1)), 0.5 - sub_pos.y / 2.0);
right = mix(right, texture_relative(image, position, vec2( 1, -1)), 0.5 - sub_pos.y / 2.0); right = mix(right, texture_relative(image, position, vec2( 1, -1)), 0.5 - sub_pos.y / 2.0);
@@ -19,13 +19,13 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
left *= sub_pos.y * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); left *= sub_pos.y * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
right *= sub_pos.y * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); right *= sub_pos.y * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
} }
else if (pos.y > 5.0 / 6.0) { else if (sub_pos.y > 5.0) {
center = mix(center, texture_relative(image, position, vec2( 0, 1)), sub_pos.y / 2.0); center = mix(center, texture_relative(image, position, vec2( 0, 1)), (sub_pos.y - 5) / 2.0);
left = mix(left, texture_relative(image, position, vec2(-1, 1)), sub_pos.y / 2.0); left = mix(left, texture_relative(image, position, vec2(-1, 1)), (sub_pos.y - 5) / 2.0);
right = mix(right, texture_relative(image, position, vec2( 1, 1)), sub_pos.y / 2.0); right = mix(right, texture_relative(image, position, vec2( 1, 1)), (sub_pos.y - 5) / 2.0);
center *= (1.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); center *= (6.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
left *= (1.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); left *= (6.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
right *= (1.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); right *= (6.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
} }
@@ -33,35 +33,35 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
vec4 midright = mix(right, center, 0.5); vec4 midright = mix(right, center, 0.5);
vec4 ret; vec4 ret;
if (pos.x < 1.0 / 6.0) { if (sub_pos.x < 1.0) {
ret = mix(vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_HIGH * left.b, 1), ret = mix(vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_HIGH * left.b, 1),
vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_LOW * left.b, 1), vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_LOW * left.b, 1),
sub_pos.x); sub_pos.x);
} }
else if (pos.x < 2.0 / 6.0) { else if (sub_pos.x < 2.0) {
ret = mix(vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_LOW * left.b, 1), ret = mix(vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_LOW * left.b, 1),
vec4(COLOR_HIGH * center.r, COLOR_HIGH * center.g, COLOR_LOW * midleft.b, 1), vec4(COLOR_HIGH * center.r, COLOR_HIGH * center.g, COLOR_LOW * midleft.b, 1),
sub_pos.x); sub_pos.x - 1);
} }
else if (pos.x < 3.0 / 6.0) { else if (sub_pos.x < 3.0) {
ret = mix(vec4(COLOR_HIGH * center.r , COLOR_HIGH * center.g, COLOR_LOW * midleft.b, 1), ret = mix(vec4(COLOR_HIGH * center.r , COLOR_HIGH * center.g, COLOR_LOW * midleft.b, 1),
vec4(COLOR_LOW * midright.r, COLOR_HIGH * center.g, COLOR_LOW * center.b, 1), vec4(COLOR_LOW * midright.r, COLOR_HIGH * center.g, COLOR_LOW * center.b, 1),
sub_pos.x); sub_pos.x - 2);
} }
else if (pos.x < 4.0 / 6.0) { else if (sub_pos.x < 4.0) {
ret = mix(vec4(COLOR_LOW * midright.r, COLOR_HIGH * center.g , COLOR_LOW * center.b, 1), ret = mix(vec4(COLOR_LOW * midright.r, COLOR_HIGH * center.g , COLOR_LOW * center.b, 1),
vec4(COLOR_LOW * right.r , COLOR_HIGH * center.g, COLOR_HIGH * center.b, 1), vec4(COLOR_LOW * right.r , COLOR_HIGH * center.g, COLOR_HIGH * center.b, 1),
sub_pos.x); sub_pos.x - 3);
} }
else if (pos.x < 5.0 / 6.0) { else if (sub_pos.x < 5.0) {
ret = mix(vec4(COLOR_LOW * right.r, COLOR_HIGH * center.g , COLOR_HIGH * center.b, 1), ret = mix(vec4(COLOR_LOW * right.r, COLOR_HIGH * center.g , COLOR_HIGH * center.b, 1),
vec4(COLOR_LOW * right.r, COLOR_LOW * midright.g, COLOR_HIGH * center.b, 1), vec4(COLOR_LOW * right.r, COLOR_LOW * midright.g, COLOR_HIGH * center.b, 1),
sub_pos.x); sub_pos.x - 4);
} }
else { else {
ret = mix(vec4(COLOR_LOW * right.r, COLOR_LOW * midright.g, COLOR_HIGH * center.b, 1), ret = mix(vec4(COLOR_LOW * right.r, COLOR_LOW * midright.g, COLOR_HIGH * center.b, 1),
vec4(COLOR_HIGH * right.r, COLOR_LOW * right.g , COLOR_HIGH * center.b, 1), vec4(COLOR_HIGH * right.r, COLOR_LOW * right.g , COLOR_HIGH * center.b, 1),
sub_pos.x); sub_pos.x - 5);
} }
return ret; return ret;

View File

@@ -16,22 +16,22 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
vec4 r2 = mix(q12, q22, s.x); vec4 r2 = mix(q12, q22, s.x);
vec2 pos = fract(position * input_resolution); vec2 pos = fract(position * input_resolution);
vec2 sub_pos = fract(position * input_resolution * 6); vec2 sub_pos = pos * 6;
float multiplier = 1.0; float multiplier = 1.0;
if (pos.y < 1.0 / 6.0) { if (sub_pos.y < 1.0) {
multiplier *= sub_pos.y * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); multiplier *= sub_pos.y * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
} }
else if (pos.y > 5.0 / 6.0) { else if (sub_pos.y > 5.0) {
multiplier *= (1.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); multiplier *= (6.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
} }
if (pos.x < 1.0 / 6.0) { if (sub_pos.x < 1.0) {
multiplier *= sub_pos.x * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); multiplier *= sub_pos.x * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
} }
else if (pos.x > 5.0 / 6.0) { else if (sub_pos.x > 5.0) {
multiplier *= (1.0 - sub_pos.x) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); multiplier *= (6.0 - sub_pos.x) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
} }
vec4 pre_shadow = mix(texture(image, position) * multiplier, mix(r1, r2, s.y), BLOOM); vec4 pre_shadow = mix(texture(image, position) * multiplier, mix(r1, r2, s.y), BLOOM);