]> git.sesse.net Git - movit/blob - resample_effect.frag
Support negative values for lift in LiftGammaGainEffect.
[movit] / resample_effect.frag
1 // DIRECTION_VERTICAL will be #defined to 1 if we are scaling vertically,
2 // and 0 otherwise.
3
4 // Implicit uniforms:
5 // uniform sampler2D PREFIX(sample_tex);
6 // uniform int PREFIX(num_samples);
7 // uniform float PREFIX(num_loops);
8 // uniform float PREFIX(sample_x_scale);
9 // uniform float PREFIX(sample_x_offset);
10 // uniform float PREFIX(slice_height);
11
12 // We put the fractional part of the offset (-0.5 to 0.5 pixels) in the weights
13 // because we have to (otherwise they'd do nothing). However, the support texture
14 // has limited numerical precision; we'd need as much of it as we can for
15 // getting the subpixel sampling right, and adding a large constant to each value
16 // will reduce the precision further. Thus, the non-fractional part of the offset
17 // is sent in through a uniform that we simply add in. (It should be said that
18 // for high values of (dst_size/num_loop), we're pretty much hosed anyway wrt.
19 // this accuracy.)
20 //
21 // Unfortunately, we cannot just do it at the beginning of the shader,
22 // since the texcoord value is used to index into the support texture,
23 // and if zoom != 1, the support texture will not wrap properly, causing
24 // us to read the wrong texels. (Also remember that whole_pixel_offset is
25 // measured in _input_ pixels and tc is in _output_ pixels, although we could
26 // compensate for that.) However, the shader should be mostly bandwidth bound
27 // and not ALU bound, so an extra add per sample shouldn't be too hopeless.
28 //
29 // Implicitly declared:
30 // uniform float PREFIX(whole_pixel_offset);
31
32 // Sample a single weight. First fetch information about where to sample
33 // and the weight from sample_tex, and then read the pixel itself.
34 vec4 PREFIX(do_sample)(vec2 tc, int i)
35 {
36         vec2 sample_tc;
37         sample_tc.x = float(i) * PREFIX(sample_x_scale) + PREFIX(sample_x_offset);
38 #if DIRECTION_VERTICAL
39         sample_tc.y = tc.y * PREFIX(num_loops);
40 #else
41         sample_tc.y = tc.x * PREFIX(num_loops);
42 #endif
43         vec2 sample = tex2D(PREFIX(sample_tex), sample_tc).rg;
44
45 #if DIRECTION_VERTICAL
46         tc.y = sample.g + (floor(sample_tc.y) * PREFIX(slice_height) + PREFIX(whole_pixel_offset));
47 #else
48         tc.x = sample.g + (floor(sample_tc.y) * PREFIX(slice_height) + PREFIX(whole_pixel_offset));
49 #endif
50         return vec4(sample.r) * INPUT(tc);
51 }
52
53 vec4 FUNCNAME(vec2 tc) {
54         vec4 sum = PREFIX(do_sample)(tc, 0);
55         for (int i = 1; i < PREFIX(num_samples); ++i) {
56                 sum += PREFIX(do_sample)(tc, i);
57         }
58         return sum;
59 }
60
61 #undef DIRECTION_VERTICAL