Add bicubic scaling

This commit is contained in:
Splendide Imaginarius 2023-10-31 12:42:24 +00:00
parent c9047da9ba
commit a56e6e0987
7 changed files with 87 additions and 2 deletions

View file

@ -81,7 +81,7 @@
// is upscaled
// 0: Nearest-Neighbor
// 1: Bilinear
// 2: (Reserved)
// 2: Bicubic
// 3: Lanczos3
// (default: 0)
//

41
shader/bicubic.frag Normal file
View file

@ -0,0 +1,41 @@
// From https://raw.githubusercontent.com/Sentmoraap/doing-sdl-right/f1a0183692abbd5d899fb432ab8dafe228a4929a/assets/bicubic.frag
// Copyright 2020 Lilian Gimenez (Sentmoraap).
// mkxp-z modifications Copyright 2022-2023 Splendide Imaginarius.
// MIT license.
uniform sampler2D texture;
uniform vec2 sourceSize;
uniform vec2 texSizeInv;
varying vec2 v_texCoord;
uniform vec2 bc;
void main()
{
vec2 pixel = v_texCoord * sourceSize + 0.5;
vec2 frac = fract(pixel);
vec2 frac2 = frac * frac;
vec2 frac3 = frac * frac2;
vec2 onePixel = texSizeInv;
pixel = floor(pixel) * texSizeInv - onePixel / 2.0;
vec4 colours[4];
// 16 reads, unoptimized but forks for every Mitchell-Netravali filter
for(int i = -1; i <= 2; i++)
{
vec4 p0 = texture2D(texture, pixel + vec2( -onePixel.x, float(i) * onePixel.y)).rgba;
vec4 p1 = texture2D(texture, pixel + vec2( 0, float(i) * onePixel.y)).rgba;
vec4 p2 = texture2D(texture, pixel + vec2( onePixel.x, float(i) * onePixel.y)).rgba;
vec4 p3 = texture2D(texture, pixel + vec2(2.0 * onePixel.x, float(i) * onePixel.y)).rgba;
colours[i + 1] = ((-bc.x / 6.0 - bc . y) * p0 + (- 1.5 * bc.x - bc.y + 2.0) * p1
+ (1.5 * bc.x + bc.y - 2.0) * p2 + (bc.x / 6.0 + bc.y) * p3) * frac3.x
+ ((0.5 * bc.x + 2.0 * bc.y) * p0 + (2.0 * bc.x + bc.y - 3.0) * p1
+ (-2.5 * bc.x - 2.0 * bc.y + 3.0) * p2 - bc.y * p3) * frac2.x
+ ((-0.5 * bc.x - bc.y) * p0 + (0.5 * bc.x + bc.y) * p2) * frac.x
+ p0 * bc.x / 6.0 + (-bc.x / 3.0 + 1.0) * p1 + p2 * bc.x / 6.0;
}
gl_FragColor = ((-bc.x / 6.0 - bc . y) * colours[0] + (- 1.5 * bc.x - bc.y + 2.0) * colours[1]
+ (1.5 * bc.x + bc.y - 2.0) * colours[2] + (bc.x / 6.0 + bc.y) * colours[3]) * frac3.y
+ ((0.5 * bc.x + 2.0 * bc.y) * colours[0] + (2.0 * bc.x + bc.y - 3.0) * colours[1]
+ (-2.5 * bc.x - 2.0 * bc.y + 3.0) * colours[2] - bc.y * colours[3]) * frac2.y
+ ((-0.5 * bc.x - bc.y) * colours[0] + (0.5 * bc.x + bc.y) * colours[2]) * frac.y
+ colours[0] * bc.x / 6.0 + (-bc.x / 3.0 + 1.0) * colours[1] + colours[2] * bc.x / 6.0;
}

View file

@ -15,6 +15,7 @@ embedded_shaders = [
'simpleAlphaUni.frag',
'tilemap.frag',
'flashMap.frag',
'bicubic.frag',
'lanczos3.frag',
'minimal.vert',
'simple.vert',

View file

@ -154,6 +154,16 @@ static void _blitBegin(FBO::ID fbo, const Vec2i &size)
switch (shState->config().smoothScaling)
{
case Bicubic:
{
BicubicShader &shader = shState->shaders().bicubic;
shader.bind();
shader.applyViewportProj();
shader.setTranslation(Vec2i());
shader.setTexSize(Vec2i(size.x, size.y));
}
break;
case Lanczos3:
{
Lanczos3Shader &shader = shState->shaders().lanczos3;
@ -234,6 +244,14 @@ void blitSource(TEXFBO &source)
{
switch (shState->config().smoothScaling)
{
case Bicubic:
{
BicubicShader &shader = shState->shaders().bicubic;
shader.bind();
shader.setTexSize(Vec2i(blitSrcWidthHires, blitSrcHeightHires));
}
break;
case Lanczos3:
{
Lanczos3Shader &shader = shState->shaders().lanczos3;

View file

@ -46,6 +46,7 @@
#include "simpleAlphaUni.frag.xxd"
#include "tilemap.frag.xxd"
#include "flashMap.frag.xxd"
#include "bicubic.frag.xxd"
#include "lanczos3.frag.xxd"
#include "minimal.vert.xxd"
#include "simple.vert.xxd"
@ -767,6 +768,20 @@ void BltShader::setOpacity(float value)
gl.Uniform1f(u_opacity, value);
}
BicubicShader::BicubicShader()
{
INIT_SHADER(simple, bicubic, BicubicShader);
ShaderBase::init();
GET_U(texOffsetX);
GET_U(sourceSize);
GET_U(bc);
// TODO: Maybe expose this as a setting?
gl.Uniform2f(u_bc, 0.0, 0.5);
}
Lanczos3Shader::Lanczos3Shader()
{
INIT_SHADER(simple, lanczos3, Lanczos3Shader);

View file

@ -341,6 +341,15 @@ protected:
GLint u_sourceSize;
};
class BicubicShader : public Lanczos3Shader
{
public:
BicubicShader();
protected:
GLint u_bc;
};
/* Global object containing all available shaders */
struct ShaderSet
{
@ -362,6 +371,7 @@ struct ShaderSet
SimpleMatrixShader simpleMatrix;
BlurShader blur;
TilemapVXShader tilemapVX;
BicubicShader bicubic;
Lanczos3Shader lanczos3;
};

View file

@ -204,7 +204,7 @@ enum InterpolationMethod
{
NearestNeighbor = 0,
Bilinear = 1,
// Reserving 2 for Bicubic
Bicubic = 2,
Lanczos3 = 3,
};