diff --git a/interpolation/grid-blend-hybrid.slangp b/interpolation/grid-blend-hybrid.slangp new file mode 100644 index 0000000..63e7cdd --- /dev/null +++ b/interpolation/grid-blend-hybrid.slangp @@ -0,0 +1,4 @@ +shaders = 1 + +shader0 = shaders/grid-blend-hybrid.slang +filter_linear0 = true \ No newline at end of file diff --git a/interpolation/shaders/grid-blend-hybrid.slang b/interpolation/shaders/grid-blend-hybrid.slang new file mode 100644 index 0000000..09f24cc --- /dev/null +++ b/interpolation/shaders/grid-blend-hybrid.slang @@ -0,0 +1,58 @@ +#version 450 + +// based on Cole Cecil's +// Scaling Pixel ARt Without Destroying It +// https://colececil.io/blog/2017/scaling-pixel-art-without-destroying-it/ + +// This shader needs bilinear filtering + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; +} params; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; +layout(location = 1) out vec2 textureCoords; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord * 1.00001; + textureCoords = vTexCoord * params.SourceSize.xy; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec2 textureCoords; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +void main() +{ + // For the current screen pixel, find its location in relation to the nearest texels). + vec2 locationWithinTexel = fract(textureCoords); + + // How many texels are in each pixel + vec2 texelsPerPixel = params.OutputSize.zw * params.SourceSize.xy; + + // Determine how much (if at all) we need to interpolate between the colors of the nearest texels + // No interpolation means it’s using nearest neighbor filtering. + // Interpolation means it’s using bilinear filtering + vec2 interpolationAmount = clamp(locationWithinTexel / texelsPerPixel, 0., 0.5) + + clamp((locationWithinTexel - 1.) / texelsPerPixel + 0.5, 0., 0.5); + + // Given the interpolation amount, calculate and return the color of the pixel. + vec2 finalTextureCoords = (floor(textureCoords) + interpolationAmount) * params.SourceSize.zw; + FragColor = vec4(texture(Source, finalTextureCoords).rgb, 1.0); +} \ No newline at end of file