ProjectArcade

Форк
0
/
upscale_bicubic.fsh 
76 строк · 2.4 Кб
1
// Bicubic upscaling shader.
2
// Implements Mitchell-Netravali class filters (aka BC-splines), see:
3
// https://en.wikipedia.org/wiki/Mitchell%E2%80%93Netravali_filters .
4

5
#ifdef GL_ES
6
precision mediump float;
7
precision mediump int;
8
#endif
9

10
uniform sampler2D sampler0;
11
varying vec2 v_position;
12

13
uniform vec2 u_texelDelta;
14
uniform vec2 u_pixelDelta;
15

16
uniform vec4 u_setting;
17
// Shader parameters (somewhat poorly named):
18
//   u_setting.x - Sharpness
19
//   u_setting.y - Anisotropy
20
// from which filter coefficients are computed as
21
//   B = 1 - Sharpness + 0.5*Anisotropy
22
//   C = 0.5 * Sharpness + Anisotropy
23

24
// Note: some popular filters are
25
//   B-spline                 - B=1, C=0   <=> Sharpness=0,   Anisotropy=0
26
//   'The' Mitchell-Netravali - B=C=1/3    <=> Sharpness=2/3, Anisotropy=0
27
//   Catmull-Rom              - B=0, C=1/2 <=> Sharpness=1,   Anisotropy=0
28

29
const vec2 HALF_PIXEL = vec2(0.5, 0.5);
30

31
vec3 rgb(int inputX, int inputY) {
32
	return texture2D(sampler0, (vec2(inputX, inputY) + HALF_PIXEL) * u_texelDelta).xyz;
33
}
34

35
vec4 getWeights(mat4 W, float t) {
36
	return W * vec4(1.0, t, t*t, t*t*t);
37
}
38

39
vec3 filterX(ivec2 inputPosFloor, int dy, vec4 w) {
40
	return
41
		w.x * rgb(inputPosFloor.x - 1, inputPosFloor.y + dy) +
42
		w.y * rgb(inputPosFloor.x    , inputPosFloor.y + dy) +
43
		w.z * rgb(inputPosFloor.x + 1, inputPosFloor.y + dy) +
44
		w.w * rgb(inputPosFloor.x + 2, inputPosFloor.y + dy);
45
}
46

47
vec4 filterBC(vec2 outputPos, float B, float C) {
48
	vec2 inputPos = outputPos / u_texelDelta - HALF_PIXEL;
49
	ivec2 inputPosFloor = ivec2(inputPos);
50
	float x = inputPos.x - float(inputPosFloor.x);
51
	float y = inputPos.y - float(inputPosFloor.y);
52
	const float r6 = 0.166666666, r3 = 0.333333333; // Precomputed 1/6 and 1/3.
53
	// Matrix for computing weights.
54
	// NOTE: column-major.
55
	mat4 W = mat4(
56
		B*r6       , 1.0-B*r3    , B*r6            , 0.0   ,
57
		-C-0.5*B   , 0.0         , C+0.5*B         , 0.0   ,
58
		2.0*C+0.5*B, C+2.0*B-3.0 , -2.0*C-2.5*B+3.0, -C    ,
59
		-C-B*r6    , -C-1.5*B+2.0, C+1.5*B-2.0     , C+B*r6);
60
	vec4 Wx = getWeights(W, x);
61
	vec4 Wy = getWeights(W, y);
62

63
	vec3 ret =
64
		Wy.x * filterX(inputPosFloor, -1, Wx) +
65
		Wy.y * filterX(inputPosFloor,  0, Wx) +
66
		Wy.z * filterX(inputPosFloor, +1, Wx) +
67
		Wy.w * filterX(inputPosFloor, +2, Wx);
68
	return vec4(ret, 1.0);
69
}
70

71
void main() {
72
	gl_FragColor.rgba = filterBC(
73
		v_position,
74
		dot(u_setting.xy, vec2(-1.0, 0.5)) + 1.0,
75
		dot(u_setting.xy, vec2(0.5, +1.0)));
76
}
77

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.