Bug #304
Problems in Bicubic&Hermite scaling filters
Description
They were found half a year ago but I forgot to submit a ticket (for some reason...?). Sorry if I misremember or provide outdated information.
fx&fy in Bicubic
"f=fract(texcoord)" only makes sense if the sampling point at "passUV" uses top-left instead of center as its coordinate.
The long version:
cubic() outputs the weight of 4 texels (one axis) in B-Spline with the assumption of them being d-1,d0,d+1,d+2 (see https://vec3.ca/bicubic-filtering-in-fewer-taps/ "The B-Spline Weighting Function")
d0 is always the texel on the left side of the sampling point so that the 4 texels are the ones whose middle point is the closet to the sampling point.
Input f is the distance of the sampling point from d0.
The correct f is shown both in above website and https://github.com/slashiee/cemu_graphic_packs/blob/master/Filters/Bicubic%20(4%20taps)/output.glsl#L23-L29
(If texcoord were top-left, "fract(texcoord)" would indeed be the distance by pretending texel to be top-left as well.)"uniform vec2 textureSrcResolution" gives the native resolution of the game, doesn't reflect the actual texture resolution if it has been changed by gfx pack rule.
Hermite is now using "uniform vec2 outputResolution", which gives the actual output resolution not the "texelSize" it requires.
"texelSize" is used to turn "passUV" from 0--1 to 0--texelSize, which is then used to locate texels or apply offsets conveniently, navtive/output resolution are not involved in this.Final textures to be resized have gl_texture_wrap_* = GL_REPEAT (BoTW's main menu, only menu not in-game), d+1 d+2 for pixels at the edge for example can be texels at other side of the texture, which causes a bright border (https://user-images.githubusercontent.com/21133512/62403404-7b170d00-b5bf-11e9-957e-f7c4baa07f02.PNG). (Also Bug #253)
If it can be overwritten GL_MIRRORED_REPEAT would be a good choice.