summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc')
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc89
1 files changed, 63 insertions, 26 deletions
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc
index f3f5513584a..a767a060b99 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc
@@ -45,6 +45,12 @@ uniform vec4 u_tex_size0;
uniform vec4 u_tex_size1;
uniform vec4 u_quad_dims;
+uniform vec4 spot_size;
+uniform vec4 spot_growth;
+uniform vec4 spot_growth_power;
+
+uniform vec4 u_interp;
+
uniform vec4 aperture_strength;
uniform vec4 aperture_brightboost;
@@ -120,9 +126,11 @@ vec4 scanlineWeights(float distance, vec4 color)
// "weights" should have a higher peak at the center of the
// scanline than for a wider beam.
#ifdef USEGAUSSIAN
- vec4 wid = 0.3 + 0.1 * pow(color, vec4_splat(3.0));
+ vec4 wid = spot_size.x + spot_growth.x * pow(color, vec4_splat(spot_growth_power.x));
vec4 weights = vec4(distance / wid);
- return 0.4 * exp(-weights * weights) / wid;
+ float maxwid = spot_size.x + spot_growth.x;
+ float norm = maxwid / ( 1.0 + exp(-1.0/(maxwid*maxwid)) );
+ return norm * exp(-weights * weights) / wid;
#else
vec4 wid = 2.0 + 2.0 * pow(color, vec4_splat(4.0));
vec4 weights = vec4_splat(distance / 0.3);
@@ -130,6 +138,55 @@ vec4 scanlineWeights(float distance, vec4 color)
#endif
}
+vec4 cubic(vec4 x, float B, float C)
+{
+ // https://en.wikipedia.org/wiki/Mitchell%E2%80%93Netravali_filters
+ vec2 a = x.yz; // components in [0,1]
+ vec2 b = x.xw; // components in [1,2]
+ vec2 a2 = a*a;
+ vec2 b2 = b*b;
+ a = (2.0-1.5*B-1.0*C)*a*a2 + (-3.0+2.0*B+C)*a2 + (1.0-(1.0/3.0)*B);
+ b = ((-1.0/6.0)*B-C)*b*b2 + (B+5.0*C)*b2 + (-2.0*B-8.0*C)*b + ((4.0/3.0)*B+4.0*C);
+ return vec4(b.x,a.x,a.y,b.y);
+}
+
+vec4 x_coeffs(vec4 x, float pos_x)
+{
+ if (u_interp.x < 0.5) { // box
+ float wid = length(vec2(dFdx(pos_x),dFdy(pos_x)));
+ float dx = clamp((0.5 + 0.5*wid - x.y)/wid, 0.0, 1.0);
+ return vec4(0.0,dx,1.0-dx,0.0);
+ } else if (u_interp.x < 1.5) { // linear
+ return vec4(0.0, 1.0-x.y, 1.0-x.z, 0.0);
+ } else if (u_interp.x < 2.5) { // Lanczos
+ // Prevent division by zero.
+ vec4 coeffs = FIX(PI * x);
+ // Lanczos2 kernel.
+ coeffs = 2.0 * sin(coeffs) * sin(coeffs / 2.0) / (coeffs * coeffs);
+ // Normalize.
+ coeffs /= dot(coeffs, vec4_splat(1.0));
+ return coeffs;
+ } else if (u_interp.x < 3.5) { // Catmull-Rom
+ return cubic(x,0.0,0.5);
+ } else if (u_interp.x < 4.5) { // Mitchell-Netravali
+ return cubic(x,1.0/3.0,1.0/3.0);
+ } else if (u_interp.x < 5.5) { // B-spline
+ return cubic(x,1.0,0.0);
+ }
+}
+
+vec4 sample_scanline(vec2 xy, vec4 coeffs, float onex)
+{
+ // Calculate the effective colour of the given
+ // scanline at the horizontal location of the current pixel,
+ // using the Lanczos coefficients.
+ vec4 col = clamp(TEX2D(xy + vec2(-onex, 0.0))*coeffs.x +
+ TEX2D(xy)*coeffs.y +
+ TEX2D(xy +vec2(onex, 0.0))*coeffs.z +
+ TEX2D(xy + vec2(2.0 * onex, 0.0))*coeffs.w , 0.0, 1.0);
+ return col;
+}
+
void main()
{
// Here's a helpful diagram to keep in mind while trying to
@@ -173,33 +230,13 @@ void main()
// Snap to the center of the underlying texel.
xy = (floor(ratio_scale) + vec2_splat(0.5)) / u_tex_size0.xy;
- // Calculate Lanczos scaling coefficients describing the effect
+ // Calculate scaling coefficients describing the effect
// of various neighbour texels in a scanline on the current
// pixel.
- vec4 coeffs = PI * vec4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x);
-
- // Prevent division by zero.
- coeffs = FIX(coeffs);
-
- // Lanczos2 kernel.
- coeffs = 2.0 * sin(coeffs) * sin(coeffs / 2.0) / (coeffs * coeffs);
-
- // Normalize.
- coeffs /= dot(coeffs, vec4_splat(1.0));
-
- // Calculate the effective colour of the current and next
- // scanlines at the horizontal location of the current pixel,
- // using the Lanczos coefficients above.
- vec4 col = clamp(TEX2D(xy + vec2(-v_one.x, 0.0))*coeffs.x +
- TEX2D(xy)*coeffs.y +
- TEX2D(xy +vec2(v_one.x, 0.0))*coeffs.z +
- TEX2D(xy + vec2(2.0 * v_one.x, 0.0))*coeffs.w , 0.0, 1.0);
-
- vec4 col2 = clamp(TEX2D(xy + vec2(-v_one.x, v_one.y))*coeffs.x +
- TEX2D(xy + vec2(0.0, v_one.y))*coeffs.y +
- TEX2D(xy + v_one)*coeffs.z +
- TEX2D(xy + vec2(2.0 * v_one.x, v_one.y))*coeffs.w , 0.0, 1.0);
+ vec4 coeffs = x_coeffs(vec4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x), ratio_scale.x);
+ vec4 col = sample_scanline(xy, coeffs, v_one.x);
+ vec4 col2 = sample_scanline(xy + vec2(0.0, v_one.y), coeffs, v_one.x);
#ifndef LINEAR_PROCESSING
col = pow(col , vec4_splat(CRTgamma.x));