From 1082942e4bfd5220c9432469f6d726c20992daf7 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Fri, 5 Jul 2019 17:11:12 +0100 Subject: [PATCH] Add sharp_bilinear/sharp_bilinear+nds_color shaders --- README.md | 4 ++ sharp_bilinear+nds_color.dfx | 27 +++++++++++ sharp_bilinear+nds_color.dsd | 92 ++++++++++++++++++++++++++++++++++++ sharp_bilinear.dfx | 27 +++++++++++ sharp_bilinear.dsd | 67 ++++++++++++++++++++++++++ 5 files changed, 217 insertions(+) create mode 100644 sharp_bilinear+nds_color.dfx create mode 100644 sharp_bilinear+nds_color.dsd create mode 100644 sharp_bilinear.dfx create mode 100644 sharp_bilinear.dsd diff --git a/README.md b/README.md index 4013100..a2332ce 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ Some shaders for [DraStic DS](https://play.google.com/store/apps/details?id=com. A very simple 'scanline' shader, based on LCD3x from RetroArch. Differs from LCD3x in that it omits the 3-band colour separation and has correctly aligned scanlines. Works well on low resolution displays (i.e. 720p). +## Sharp Bilinear + +A port of the 'sharp-bilinear'/'sharp-bilinear-simple' shader from RetroArch. Creates sharp pixels without scaling artefacts by performing an automatic optimal integer prescale followed by linear downscaling to the display size. + ## zFast LCD A port of the 'zfast_lcd' shader from RetroArch. Creates an LCD effect by adding a subtle grid lattice to the screen. REQUIRES a high resolution display (at least 1080p). Works best with integer screen scaling, but fine without. diff --git a/sharp_bilinear+nds_color.dfx b/sharp_bilinear+nds_color.dfx new file mode 100644 index 0000000..df87a2c --- /dev/null +++ b/sharp_bilinear+nds_color.dfx @@ -0,0 +1,27 @@ +// sharp_bilinear+nds_color shader +============================================= + +name=Sharp Bilinear + NDS Color +textures=1 + + + +#if GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#endif + + + +input=framebuffer +min_filter=GL_LINEAR +mag_filter=GL_LINEAR + + + +shader=sharp_bilinear+nds_color.dsd +sampler:u_texture=0 + diff --git a/sharp_bilinear+nds_color.dsd b/sharp_bilinear+nds_color.dsd new file mode 100644 index 0000000..2e79335 --- /dev/null +++ b/sharp_bilinear+nds_color.dsd @@ -0,0 +1,92 @@ +// sharp_bilinear+nds_color - This is an integer prescale filter that should be combined +// with bilinear hardware filtering (GL_LINEAR filter or some such) to achieve +// a smooth scaling result with minimum blur. This is good for pixel graphics +// that are scaled by non-integer factors. Also applies colour correction to mimic +// the display characteristics of an NDS Phat +// +// - Original 'sharp_bilinear' code copyright (C) rsn8887 & TheMaister and +// released into the public domain +// +// - Original 'nds_color' code written by hunterk, modified by Pokefan531 and +// released into the public domain +// +// 'Ported' (i.e. copy/paste) to DraStic format by jdgleaver +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +============================================= + + + +attribute vec2 a_vertex_coordinate; +attribute vec2 a_texture_coordinate; + +uniform vec4 u_texture_size; +uniform vec2 u_target_size; + +varying vec2 precalc_texel; +varying vec2 precalc_scale; + +void main() +{ + gl_Position = vec4(a_vertex_coordinate.xy, 0.0, 1.0); + + precalc_texel = a_texture_coordinate * u_texture_size.zw; + precalc_scale = floor(u_target_size.xy / u_texture_size.zw) + 1.0; +} + + + + + +// Colour defines... +#define target_gamma 2.2 +#define display_gamma 2.2 +#define r 0.85 +#define g 0.655 +#define b 0.865 +#define rg 0.095 +#define rb 0.06 +#define gr 0.20 +#define gb 0.075 +#define br -0.05 +#define bg 0.25 + +uniform sampler2D u_texture; + +uniform vec4 u_texture_size; +uniform vec2 u_target_size; + +varying vec2 precalc_texel; +varying vec2 precalc_scale; + +void main() +{ + vec2 texel_floored = floor(precalc_texel); + vec2 s = fract(precalc_texel); + vec2 region_range = 0.5 - 0.5 / precalc_scale; + + // Figure out where in the texel to sample to get correct pre-scaled bilinear. + // Uses the hardware bilinear interpolator to avoid having to sample 4 times manually. + + vec2 center_dist = s - 0.5; + vec2 f = (center_dist - clamp(center_dist, -region_range, region_range)) * precalc_scale + 0.5; + + vec2 mod_texel = texel_floored + f; + + // Get colour sample and apply colour correction + vec3 colour = pow(texture2D(u_texture, mod_texel / u_texture_size.zw).rgb, vec3(target_gamma)); + colour = clamp(colour, 0.0, 1.0); + colour = pow( + mat3(r, rg, rb, + gr, g, gb, + br, bg, b) * colour, + vec3(1.0 / display_gamma) + ); + + gl_FragColor = vec4(colour.rgb, 1.0); +} + + diff --git a/sharp_bilinear.dfx b/sharp_bilinear.dfx new file mode 100644 index 0000000..944297d --- /dev/null +++ b/sharp_bilinear.dfx @@ -0,0 +1,27 @@ +// sharp_bilinear shader +============================================= + +name=Sharp Bilinear +textures=1 + + + +#if GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#endif + + + +input=framebuffer +min_filter=GL_LINEAR +mag_filter=GL_LINEAR + + + +shader=sharp_bilinear.dsd +sampler:u_texture=0 + diff --git a/sharp_bilinear.dsd b/sharp_bilinear.dsd new file mode 100644 index 0000000..8254f2f --- /dev/null +++ b/sharp_bilinear.dsd @@ -0,0 +1,67 @@ +// sharp_bilinear - This is an integer prescale filter that should be combined +// with bilinear hardware filtering (GL_LINEAR filter or some such) to achieve +// a smooth scaling result with minimum blur. This is good for pixel graphics +// that are scaled by non-integer factors. +// +// Original code copyright (C) rsn8887 & TheMaister and released into the +// public domain +// +// 'Ported' (i.e. copy/paste) to DraStic format by jdgleaver +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +============================================= + + + +attribute vec2 a_vertex_coordinate; +attribute vec2 a_texture_coordinate; + +uniform vec4 u_texture_size; +uniform vec2 u_target_size; + +varying vec2 precalc_texel; +varying vec2 precalc_scale; + +void main() +{ + gl_Position = vec4(a_vertex_coordinate.xy, 0.0, 1.0); + + precalc_texel = a_texture_coordinate * u_texture_size.zw; + precalc_scale = floor(u_target_size.xy / u_texture_size.zw) + 1.0; +} + + + + + +uniform sampler2D u_texture; + +uniform vec4 u_texture_size; +uniform vec2 u_target_size; + +varying vec2 precalc_texel; +varying vec2 precalc_scale; + +void main() +{ + vec2 texel_floored = floor(precalc_texel); + vec2 s = fract(precalc_texel); + vec2 region_range = 0.5 - 0.5 / precalc_scale; + + // Figure out where in the texel to sample to get correct pre-scaled bilinear. + // Uses the hardware bilinear interpolator to avoid having to sample 4 times manually. + + vec2 center_dist = s - 0.5; + vec2 f = (center_dist - clamp(center_dist, -region_range, region_range)) * precalc_scale + 0.5; + + vec2 mod_texel = texel_floored + f; + + vec3 colour = texture2D(u_texture, mod_texel / u_texture_size.zw).rgb; + + gl_FragColor = vec4(colour.rgb, 1.0); +} + +