Developer Documentation
FilterKernels.hh
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 
43 
44 #pragma once
45 
46 
47 #include <ACG/Config/ACGDefines.hh>
48 #include <ACG/Math/GLMatrixT.hh>
49 #include <ACG/GL/gl.hh>
50 
51 #include <QStringList>
52 #include <QImage>
53 #include <vector>
54 
55 
56 
57 // Forward Declaration
58 namespace GLSL
59 {
60  class Program;
61 }
62 
63 namespace ACG
64 {
65 
66 // Forward Declaration
67 class FBO;
68 
69 
70 
71 class ACGDLLEXPORT BaseSeparableFilterKernel
72 {
73 public:
74 
75  /* \brief Create separable filter
76  *
77  * @param _texWidth width of input texture
78  * @param _texHeight height of input texture
79  * @param _internalfmt internal gl format of the texture
80  */
81  BaseSeparableFilterKernel(int _texWidth, int _texHeight, GLenum _internalfmt = GL_RGBA);
82 
84  virtual ~BaseSeparableFilterKernel();
85 
86 
87  /* \brief Execute filter
88  *
89  * Perform the two filter passes.
90  * If a custom fbo and a _tempColorAttachment is provided, the first pass is
91  * rendered into that temporary render texture.
92  * If a custom fbo and a _dstColorAttachment is provided, the second pass is
93  * rendered into that destination render texture.
94  *
95  * If _dstFBO or _tempColorAttachment is invalid, an internal fbo is created as target for the first pass.
96  * If _dstFBO or _dstColorAttachment is invalid, the second pass renders into whatever is currently bound as render target.
97  *
98  * @param _srcTexture 2d input texture
99  * @param _dstFBO custom target fbo (optional)
100  * @param _dstColorAttachment target attachment of the custom target fbo (optional)
101  * @param _tempColorAttachment temporary attachment of the custom fbo, that is different from _dstColorAttachment (optional)
102  * @return true on success, false otherwise
103  */
104  bool execute(GLuint _srcTexture, ACG::FBO* _dstFBO = 0, GLuint _dstColorAttachment = GL_COLOR_ATTACHMENT0, GLuint _tempColorAttachment = 0);
105 
106 
107  /* \brief Resize input texture
108  *
109  * @param _texWidth new input texture width
110  * @param _texHeight new input texture height
111  */
112  void resizeInput(int _texWidth, int _texHeight);
113 
115  int texWidth() const {return texWidth_;}
116 
118  int texHeight() const {return texHeight_;}
119 
121  const ACG::Vec2f& texelSize() const {return texelSize_;}
122 
124  GLenum internalFormat() const {return internalfmt_;}
125 
126 protected:
127 
128  /* \brief Setup shader with uniforms
129  *
130  * @param _pass pass number: 0 or 1
131  * @param _scrTex source texture for pass
132  * @return shader program for screen quad
133  */
134  virtual GLSL::Program* setupPass(int _pass, GLuint _srcTex) = 0;
135 
136 
137  /* \brief Update kernel after resizing
138  *
139  */
140  virtual void updateKernel() = 0;
141 
142 private:
143 
144  int texWidth_,
145  texHeight_;
146 
147  GLenum internalfmt_,
148  externalfmt_;
149 
150  // size of a texel in uv space
151  ACG::Vec2f texelSize_;
152 
153  // temp render targets if none supplied by user
154  // attachment0 : target for first axis pass
155  ACG::FBO* tempRT_;
156 };
157 
158 
159 // separable 2d gaussian blur
161 {
162 public:
163 
164  /* \brief Create separable gauss filter
165  *
166  * @param _texWidth width of input texture
167  * @param _texHeight height of input texture
168  * @param _blurRadius radius in pixel coords of the blur kernel
169  * @param _blurSigma blur smoothness, standard deviation of the gaussian function
170  * @param _internalfmt internal gl format of the texture
171  */
172  GaussianBlurFilter(int _texWidth, int _texHeight, int _blurRadius, float _blurSigma = 1.0f, GLenum _internalfmt = GL_RGBA);
173 
175  virtual ~GaussianBlurFilter();
176 
177  /* \brief Change kernel settings
178  *
179  * @param _blurRadius new radius
180  * @param _blurSigma new sigma
181  */
182  void setKernel(int _blurRadius, float _blurSigma);
183 
185  int radius() const {return radius_;}
186 
188  int samples() const {return samples_;}
189 
191  int sigma() const {return sigma_;}
192 
194  const std::vector<ACG::Vec2f>& offsetsX() const {return offsetsX_;}
195 
197  const std::vector<ACG::Vec2f>& offsetsY() const {return offsetsY_;}
198 
200  const std::vector<float>& weights() const {return weights_;}
201 
202 protected:
203 
204  virtual GLSL::Program* setupPass(int _pass, GLuint _srcTex);
205 
206  void updateKernel();
207 
208 private:
209 
210  int radius_,
211  samples_;
212 
214  float sigma_;
215 
217  QStringList macros_;
218 
220  std::vector<ACG::Vec2f> offsetsX_;
221  std::vector<ACG::Vec2f> offsetsY_;
222 
224  std::vector<float> weights_;
225 };
226 
227 
228 // bilateral blur: gaussian blur with silhouette preservation
230 {
231 public:
232 
233  /* \brief Create bilateral filter
234  *
235  * @param _texWidth width of input texture
236  * @param _texHeight height of input texture
237  * @param _blurRadius radius in pixel coords of the blur kernel
238  * @param _blurSigmaS blur smoothness in spatial distance (here distance in pixel coords)
239  * @param _blurSigmaR blur smoothness in range distance (here linear view space difference)
240  * @param _internalfmt internal gl format of the texture
241  */
242  BilateralBlurFilter(int _texWidth, int _texHeight, int _blurRadius, float _blurSigmaS = 1.0f, float blurSigmaR = 1.0f, GLenum _internalfmt = GL_RGBA);
243 
245  virtual ~BilateralBlurFilter();
246 
247 
248  /* \brief Set dynamic params before calling execute()
249  *
250  * @param _proj projection matrix
251  * @param _depthTex depthbuffer texture (nonlinear depths)
252  */
253  void setParams(const ACG::GLMatrixf& _proj, GLuint _depthTex)
254  {
255  proj_ = _proj;
256  depthTex_ = _depthTex;
257  }
258 
259 
260  /* \brief Change kernel settings
261  *
262  * @param _blurRadius new radius
263  * @param _blurSigmaS new spatial smoothness
264  * @param _blurSigmaR new range smoothness
265  */
266  void setKernel(int _blurRadius, float _blurSigmaS, float _blurSigmaR);
267 
268 
270  int radius() const {return radius_;}
271 
273  int samples() const {return samples_;}
274 
276  const ACG::Vec2f& sigma() const {return sigma_;}
277 
279  const std::vector<ACG::Vec2f>& offsetsX() const {return offsetsX_;}
280 
282  const std::vector<ACG::Vec2f>& offsetsY() const {return offsetsY_;}
283 
284 protected:
285  virtual GLSL::Program* setupPass(int _pass, GLuint _srcTex);
286 
287  void updateKernel();
288 
289 private:
290 
291  int radius_,
292  samples_;
293 
296 
299 
301  std::vector<ACG::Vec2f> offsetsX_;
302  std::vector<ACG::Vec2f> offsetsY_;
303 
305  std::vector<float> spatialKernel_;
306 
308  QStringList macros_;
309 
310  ACG::GLMatrixf proj_;
311  GLuint depthTex_;
312 };
313 
314 
315 class ACGDLLEXPORT RadialBlurFilter
316 {
317 public:
318 
319  /* \brief Create radial blur filter
320  *
321  * @param _numSamples number of kernel samples
322  */
323  explicit RadialBlurFilter(int _numSamples);
324 
326  virtual ~RadialBlurFilter() {}
327 
328  /* \brief Perform radial blur
329  *
330  * Writes to currently bound render target.
331  * A good intensity range for light to very strong blur is [0.0025, 0.01].
332  *
333  * @param _srcTexture input 2d texture
334  * @param _blurRadius blur radius in uv space
335  * @param _blurIntensity intensity, quadratic distance factor
336  * @param _blurCenter center in uv space
337  */
338  bool execute(GLuint _srcTexture, float _blurRadius = 1.0f, float _blurIntensity = 0.0025f, const ACG::Vec2f& _blurCenter = ACG::Vec2f(0.5f, 0.5f));
339 
340 
341  /* \brief Change kernel settings
342  *
343  * @param _numSamples new sample count
344  */
345  void setKernel(int _numSamples);
346 
348  int samples() const {return samples_;}
349 
350 private:
351 
352  int samples_;
353 
354  QStringList macros_;
355 };
356 
357 
358 class ACGDLLEXPORT PoissonBlurFilter
359 {
360 public:
361 
362  /* \brief Create poisson blur filter
363  *
364  * @param _radius radius of poisson disk
365  * @param _sampleDistance min distance between two samples
366  * @param _numTries number of tries per sample to find the next sample
367  * @param _disk should samples lie inside a disk of radius r or inside square [-r/2, -r/2] x [r/2, r/2]
368  * @param _tilingCheck check min distance also across borders in a repeat-tiled kernel grid
369  */
370  PoissonBlurFilter(float _radius, float _sampleDistance, int _numTries = 30, bool _disk = true, bool _tilingCheck = false);
371 
373  virtual ~PoissonBlurFilter();
374 
375  /* \brief Perform poisson blur
376  *
377  * Writes to currently bound render target.
378  *
379  * @param _srcTex input 2d texture
380  * @param _kernelScale kernel radius scaling factor
381  */
382  bool execute(GLuint _srcTex, float _kernelScale = 1.0f);
383 
384 
386  float radius() const {return radius_;}
387 
389  int numSamples() const {return int(samples_.size());}
390 
392  float sampleDistance() const {return sampleDistance_;}
393 
395  int numTries() const {return numTries_;}
396 
398  bool disk() const { return disk_; }
399 
401  const std::vector<ACG::Vec2f>& samples() const {return samples_;}
402 
404  void dumpSamples(const char* _filename);
405 
407  void plotSamples(QImage* _image);
408 
409 private:
410 
411  // sampling settings
412  float radius_;
413  float sampleDistance_;
414  int numTries_;
415  bool disk_;
416 
417  // poisson disk
418  std::vector<ACG::Vec2f> samples_;
419 
420  // scaled samples
421  std::vector<ACG::Vec2f> samplesScaled_;
422 
423  // shader macros
424  QStringList macros_;
425 };
426 
427 
428 
429 }
This namespace contains all the classes and functions for handling GLSL shader and program objects...
Definition: AntiAliasing.hh:66
Namespace providing different geometric functions concerning angles.
int numTries() const
number of iterations per sample
const std::vector< ACG::Vec2f > & offsetsX() const
sample offsets along x direction
QStringList macros_
shader macros
const ACG::Vec2f & texelSize() const
texel size in uv space
std::vector< ACG::Vec2f > offsetsX_
filter taps
int samples() const
number of samples
GLenum internalFormat() const
internal format of the input texture
const std::vector< float > & weights() const
sample weights
const std::vector< ACG::Vec2f > & offsetsY() const
sample offsets along y direction
int samples() const
number of samples
virtual ~RadialBlurFilter()
Class destructor.
int numSamples() const
number of samples
GLSL program class.
Definition: GLSLShader.hh:211
float radius() const
radius
const std::vector< ACG::Vec2f > & samples() const
disk sample offsets
const std::vector< ACG::Vec2f > & offsetsX() const
sample offsets along x direction
ACG::Vec2f sigma2Rcp_
-1 / (2 * sigma^2)
std::vector< float > spatialKernel_
precomputed sample -r^2 / (2 * sigma_s^2)
int texWidth() const
input texture width
const std::vector< ACG::Vec2f > & offsetsY() const
sample offsets along y direction
std::vector< float > weights_
kernel weights
int texHeight() const
input texture height
int samples() const
number of samples
bool disk() const
samples inside disk or square area
const ACG::Vec2f & sigma() const
blur (sigmaS, sigmaR)
Definition: FBO.hh:71
QStringList macros_
shader macros
int radius() const
radius
ACG::Vec2f sigma_
(sigmaS, sigmaR)
std::vector< ACG::Vec2f > offsetsX_
filter taps
float sampleDistance() const
min distance between two samples
int radius() const
radius
int sigma() const
blur sigma