FastUIDraw
fastuidraw_texture_fetch.glsl.hpp
Go to the documentation of this file.
1 /*!
2  * \file fastuidraw_texture_fetch.glsl.hpp
3  * \brief file fastuidraw_texture_fetch.glsl.hpp
4  *
5  * Copyright 2019 by Intel.
6  *
7  * Contact: kevin.rogovin@gmail.com
8  *
9  * This Source Code Form is subject to the
10  * terms of the Mozilla Public License, v. 2.0.
11  * If a copy of the MPL was not distributed with
12  * this file, You can obtain one at
13  * http://mozilla.org/MPL/2.0/.
14  *
15  * \author Kevin Rogovin <kevin.rogovin@gmail.com>
16  *
17  */
18 
19 
20 
21 /*!\addtogroup GLSLVertFragCode
22  * @{
23  */
24 
25 ///@cond
26 vec4
27 fastuidraw_cubic_weights(float x)
28 {
29  float x_squared = x * x;
30  float x_cubed = x_squared * x;
31  float one_minus_x = 1.0 - x;
32  float one_minus_x_squared = one_minus_x * one_minus_x;
33  float one_minus_x_cubed = one_minus_x_squared * one_minus_x;
34  vec4 w;
35 
36  w.x = one_minus_x_cubed;
37  w.y = 3.0 * x_cubed - 6.0 * x_squared + 4.0;
38  w.z = 3.0 * one_minus_x_cubed - 6.0 * one_minus_x_squared + 4.0;
39  w.w = x_cubed;
40  return w / 6.0;
41 }
42 ///@endcond
43 
44 /*!
45  * \brief Peform nearest filtering on a sampler2D
46  * \param surface the surface from which to sample
47  * \param texel_coord the texel coordinate (not texture coordinate), i.e.
48  * the coordinate in pixels from which to sample
49  * \param lod the level of detail (ala textureLod() of glsl)
50  */
51 vec4
52 fastuidraw_nearest_filter_texture(in sampler2D surface, in vec2 texel_coord, in float lod)
53 {
54  vec2 adjusted;
55  int L;
56 
57  L = int(ceil(lod));
58  adjusted = texel_coord / float(1 << L);
59  return texelFetch(surface, ivec2(adjusted), L);
60 }
61 
62 /*!
63  * \brief Peform linear filtering on a sampler2D
64  * \param surface the surface from which to sample
65  * \param texel_coord the texel coordinate (not texture coordinate), i.e.
66  * the coordinate in pixels from which to sample
67  * \param lod the level of detail (ala textureLod() of glsl)
68  */
69 vec4
70 fastuidraw_linear_filter_texture(in sampler2D surface, in vec2 texel_coord, in float lod)
71 {
72  vec2 recip_sz = 1.0 / vec2(textureSize(surface, 0));
73  return textureLod(surface, texel_coord * recip_sz, lod);
74 }
75 
76 /*!
77  * \brief Peform cubic filtering on a sampler2D
78  * \param surface the surface from which to sample
79  * \param texel_coord the texel coordinate (not texture coordinate), i.e.
80  * the coordinate in pixels from which to sample
81  */
82 vec4
83 fastuidraw_cubic_filter_texture(in sampler2D surface, in vec2 texel_coord)
84 {
85  vec2 recip_sz = 1.0 / vec2(textureSize(surface, 0));
86  vec2 fract_texel_coord, linear_weight;
87  vec4 x_weights, y_weights;
88  vec4 corner_coords, weight_sums, texture_coords;
89  vec4 t00, t10, t01, t11;
90 
91  /* Cubic filtering by realizing cubic-filtering as repeated
92  * bilinear filtering, see GPU Gems 2, Chapter 20.
93  * Code inspired by StackOverflow (http://stackoverflow.com/questions/13501081/efficient-bicubic-filtering-code-in-glsl)
94  * and from Shiny Pixels (http://vec3.ca/bicubic-filtering-in-fewer-taps/)
95  */
96  texel_coord -= vec2(0.5, 0.5);
97  fract_texel_coord = fract(texel_coord);
98  texel_coord -= fract_texel_coord;
99 
100  x_weights = fastuidraw_cubic_weights(fract_texel_coord.x);
101  y_weights = fastuidraw_cubic_weights(fract_texel_coord.y);
102 
103  corner_coords = texel_coord.xxyy;
104  corner_coords.xz -= vec2(0.5);
105  corner_coords.yw += vec2(1.5);
106  weight_sums = vec4(x_weights.x + x_weights.y, x_weights.z + x_weights.w,
107  y_weights.x + y_weights.y, y_weights.z + y_weights.w);
108 
109  texture_coords = corner_coords + vec4(x_weights.yw, y_weights.yw) / weight_sums;
110  texture_coords *= recip_sz.xxyy;
111 
112  t00 = textureLod(surface, texture_coords.xz, 0.0);
113  t10 = textureLod(surface, texture_coords.yz, 0.0);
114  t01 = textureLod(surface, texture_coords.xw, 0.0);
115  t11 = textureLod(surface, texture_coords.yw, 0.0);
116 
117  linear_weight.x = weight_sums.y / (weight_sums.x + weight_sums.y);
118  linear_weight.y = weight_sums.w / (weight_sums.z + weight_sums.w);
119 
120  return mix(mix(t00, t10, linear_weight.x),
121  mix(t01, t11, linear_weight.x),
122  linear_weight.y);
123 }
124 /*! @} */
vec4 fastuidraw_nearest_filter_texture(in sampler2D surface, in vec2 texel_coord, in float lod)
Peform nearest filtering on a sampler2D.
vecN< float, 2 > vec2
Definition: vecN.hpp:1231
vecN< float, 4 > vec4
Definition: vecN.hpp:1239
vecN< int32_t, 2 > ivec2
Definition: vecN.hpp:1265
vec4 fastuidraw_linear_filter_texture(in sampler2D surface, in vec2 texel_coord, in float lod)
Peform linear filtering on a sampler2D.
vec4 fastuidraw_cubic_filter_texture(in sampler2D surface, in vec2 texel_coord)
Peform cubic filtering on a sampler2D.
reference x(void)
Definition: vecN.hpp:435