mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-24 15:53:45 +02:00
Add bicubic scaling
This commit is contained in:
parent
c9047da9ba
commit
a56e6e0987
7 changed files with 87 additions and 2 deletions
|
@ -81,7 +81,7 @@
|
||||||
// is upscaled
|
// is upscaled
|
||||||
// 0: Nearest-Neighbor
|
// 0: Nearest-Neighbor
|
||||||
// 1: Bilinear
|
// 1: Bilinear
|
||||||
// 2: (Reserved)
|
// 2: Bicubic
|
||||||
// 3: Lanczos3
|
// 3: Lanczos3
|
||||||
// (default: 0)
|
// (default: 0)
|
||||||
//
|
//
|
||||||
|
|
41
shader/bicubic.frag
Normal file
41
shader/bicubic.frag
Normal 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;
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ embedded_shaders = [
|
||||||
'simpleAlphaUni.frag',
|
'simpleAlphaUni.frag',
|
||||||
'tilemap.frag',
|
'tilemap.frag',
|
||||||
'flashMap.frag',
|
'flashMap.frag',
|
||||||
|
'bicubic.frag',
|
||||||
'lanczos3.frag',
|
'lanczos3.frag',
|
||||||
'minimal.vert',
|
'minimal.vert',
|
||||||
'simple.vert',
|
'simple.vert',
|
||||||
|
|
|
@ -154,6 +154,16 @@ static void _blitBegin(FBO::ID fbo, const Vec2i &size)
|
||||||
|
|
||||||
switch (shState->config().smoothScaling)
|
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:
|
case Lanczos3:
|
||||||
{
|
{
|
||||||
Lanczos3Shader &shader = shState->shaders().lanczos3;
|
Lanczos3Shader &shader = shState->shaders().lanczos3;
|
||||||
|
@ -234,6 +244,14 @@ void blitSource(TEXFBO &source)
|
||||||
{
|
{
|
||||||
switch (shState->config().smoothScaling)
|
switch (shState->config().smoothScaling)
|
||||||
{
|
{
|
||||||
|
case Bicubic:
|
||||||
|
{
|
||||||
|
BicubicShader &shader = shState->shaders().bicubic;
|
||||||
|
shader.bind();
|
||||||
|
shader.setTexSize(Vec2i(blitSrcWidthHires, blitSrcHeightHires));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
case Lanczos3:
|
case Lanczos3:
|
||||||
{
|
{
|
||||||
Lanczos3Shader &shader = shState->shaders().lanczos3;
|
Lanczos3Shader &shader = shState->shaders().lanczos3;
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "simpleAlphaUni.frag.xxd"
|
#include "simpleAlphaUni.frag.xxd"
|
||||||
#include "tilemap.frag.xxd"
|
#include "tilemap.frag.xxd"
|
||||||
#include "flashMap.frag.xxd"
|
#include "flashMap.frag.xxd"
|
||||||
|
#include "bicubic.frag.xxd"
|
||||||
#include "lanczos3.frag.xxd"
|
#include "lanczos3.frag.xxd"
|
||||||
#include "minimal.vert.xxd"
|
#include "minimal.vert.xxd"
|
||||||
#include "simple.vert.xxd"
|
#include "simple.vert.xxd"
|
||||||
|
@ -767,6 +768,20 @@ void BltShader::setOpacity(float value)
|
||||||
gl.Uniform1f(u_opacity, 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()
|
Lanczos3Shader::Lanczos3Shader()
|
||||||
{
|
{
|
||||||
INIT_SHADER(simple, lanczos3, Lanczos3Shader);
|
INIT_SHADER(simple, lanczos3, Lanczos3Shader);
|
||||||
|
|
|
@ -341,6 +341,15 @@ protected:
|
||||||
GLint u_sourceSize;
|
GLint u_sourceSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BicubicShader : public Lanczos3Shader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BicubicShader();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GLint u_bc;
|
||||||
|
};
|
||||||
|
|
||||||
/* Global object containing all available shaders */
|
/* Global object containing all available shaders */
|
||||||
struct ShaderSet
|
struct ShaderSet
|
||||||
{
|
{
|
||||||
|
@ -362,6 +371,7 @@ struct ShaderSet
|
||||||
SimpleMatrixShader simpleMatrix;
|
SimpleMatrixShader simpleMatrix;
|
||||||
BlurShader blur;
|
BlurShader blur;
|
||||||
TilemapVXShader tilemapVX;
|
TilemapVXShader tilemapVX;
|
||||||
|
BicubicShader bicubic;
|
||||||
Lanczos3Shader lanczos3;
|
Lanczos3Shader lanczos3;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -204,7 +204,7 @@ enum InterpolationMethod
|
||||||
{
|
{
|
||||||
NearestNeighbor = 0,
|
NearestNeighbor = 0,
|
||||||
Bilinear = 1,
|
Bilinear = 1,
|
||||||
// Reserving 2 for Bicubic
|
Bicubic = 2,
|
||||||
Lanczos3 = 3,
|
Lanczos3 = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue