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
160 class ACGDLLEXPORT GaussianBlurFilter : public BaseSeparableFilterKernel
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
229 class ACGDLLEXPORT BilateralBlurFilter : public BaseSeparableFilterKernel
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
295 ACG::Vec2f sigma_;
296
298 ACG::Vec2f sigma2Rcp_;
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 }
GLSL
This namespace contains all the classes and functions for handling GLSL shader and program objects...
Definition: AntiAliasing.hh:66
ACG
Namespace providing different geometric functions concerning angles.
Definition: BaseObjectData.hh:68
ACG::PoissonBlurFilter::numTries
int numTries() const
number of iterations per sample
Definition: FilterKernels.hh:395
ACG::GaussianBlurFilter::offsetsX
const std::vector< ACG::Vec2f > & offsetsX() const
sample offsets along x direction
Definition: FilterKernels.hh:194
ACG::BilateralBlurFilter::macros_
QStringList macros_
shader macros
Definition: FilterKernels.hh:308
ACG::BaseSeparableFilterKernel::texelSize
const ACG::Vec2f & texelSize() const
texel size in uv space
Definition: FilterKernels.hh:121
ACG::BilateralBlurFilter::offsetsX_
std::vector< ACG::Vec2f > offsetsX_
filter taps
Definition: FilterKernels.hh:301
ACG::BilateralBlurFilter::samples
int samples() const
number of samples
Definition: FilterKernels.hh:273
ACG::BaseSeparableFilterKernel::internalFormat
GLenum internalFormat() const
internal format of the input texture
Definition: FilterKernels.hh:124
ACG::GaussianBlurFilter::weights
const std::vector< float > & weights() const
sample weights
Definition: FilterKernels.hh:200
ACG::BilateralBlurFilter::offsetsY
const std::vector< ACG::Vec2f > & offsetsY() const
sample offsets along y direction
Definition: FilterKernels.hh:282
ACG::BaseSeparableFilterKernel
Definition: FilterKernels.hh:71
ACG::RadialBlurFilter::samples
int samples() const
number of samples
Definition: FilterKernels.hh:348
ACG::RadialBlurFilter::~RadialBlurFilter
virtual ~RadialBlurFilter()
Class destructor.
Definition: FilterKernels.hh:326
ACG::PoissonBlurFilter::numSamples
int numSamples() const
number of samples
Definition: FilterKernels.hh:389
ACG::BilateralBlurFilter
Definition: FilterKernels.hh:229
GLSL::Program
GLSL program class.
Definition: GLSLShader.hh:211
ACG::PoissonBlurFilter::radius
float radius() const
radius
Definition: FilterKernels.hh:386
ACG::PoissonBlurFilter::samples
const std::vector< ACG::Vec2f > & samples() const
disk sample offsets
Definition: FilterKernels.hh:401
ACG::BilateralBlurFilter::offsetsX
const std::vector< ACG::Vec2f > & offsetsX() const
sample offsets along x direction
Definition: FilterKernels.hh:279
ACG::BilateralBlurFilter::sigma2Rcp_
ACG::Vec2f sigma2Rcp_
-1 / (2 * sigma^2)
Definition: FilterKernels.hh:298
ACG::GLMatrixT< float >
ACG::BilateralBlurFilter::spatialKernel_
std::vector< float > spatialKernel_
precomputed sample -r^2 / (2 * sigma_s^2)
Definition: FilterKernels.hh:305
ACG::BaseSeparableFilterKernel::texWidth
int texWidth() const
input texture width
Definition: FilterKernels.hh:115
ACG::GaussianBlurFilter::sigma_
float sigma_
blur std
Definition: FilterKernels.hh:214
ACG::GaussianBlurFilter::offsetsY
const std::vector< ACG::Vec2f > & offsetsY() const
sample offsets along y direction
Definition: FilterKernels.hh:197
ACG::GaussianBlurFilter::weights_
std::vector< float > weights_
kernel weights
Definition: FilterKernels.hh:224
ACG::PoissonBlurFilter
Definition: FilterKernels.hh:358
ACG::BaseSeparableFilterKernel::texHeight
int texHeight() const
input texture height
Definition: FilterKernels.hh:118
ACG::GaussianBlurFilter
Definition: FilterKernels.hh:160
ACG::GaussianBlurFilter::samples
int samples() const
number of samples
Definition: FilterKernels.hh:188
ACG::PoissonBlurFilter::disk
bool disk() const
samples inside disk or square area
Definition: FilterKernels.hh:398
ACG::BilateralBlurFilter::sigma
const ACG::Vec2f & sigma() const
blur (sigmaS, sigmaR)
Definition: FilterKernels.hh:276
ACG::FBO
Definition: FBO.hh:71
ACG::GaussianBlurFilter::macros_
QStringList macros_
shader macros
Definition: FilterKernels.hh:217
ACG::BilateralBlurFilter::radius
int radius() const
radius
Definition: FilterKernels.hh:270
ACG::BilateralBlurFilter::sigma_
ACG::Vec2f sigma_
(sigmaS, sigmaR)
Definition: FilterKernels.hh:295
ACG::GaussianBlurFilter::offsetsX_
std::vector< ACG::Vec2f > offsetsX_
filter taps
Definition: FilterKernels.hh:220
OpenMesh::VectorT
Definition: Vector11T.hh:83
ACG::RadialBlurFilter
Definition: FilterKernels.hh:315
ACG::PoissonBlurFilter::sampleDistance
float sampleDistance() const
min distance between two samples
Definition: FilterKernels.hh:392
ACG::GaussianBlurFilter::radius
int radius() const
radius
Definition: FilterKernels.hh:185
ACG::GaussianBlurFilter::sigma
int sigma() const
blur sigma
Definition: FilterKernels.hh:191