diff options
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.sc | 89 |
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)); |