Skip to content

Commit 6536797

Browse files
Turns out one needs to wrap the Derivative filter at both ends.
1 parent 834f537 commit 6536797

File tree

6 files changed

+98
-92
lines changed

6 files changed

+98
-92
lines changed

examples_tests/47.DerivMapTest/ApplicationHandler.cpp

Lines changed: 93 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -62,41 +62,8 @@ void ApplicationHandler::presentImageOnTheScreen(irr::core::smart_refctd_ptr<irr
6262

6363
driver->updateDescriptorSets(1u, &write, 0u, nullptr);
6464

65-
std::string viewType;
66-
auto getCurrentGPUPipeline = [&]()
67-
{
68-
switch (gpuImageView->getCreationParameters().viewType)
69-
{
70-
case IImageView<IGPUImage>::ET_2D:
71-
{
72-
viewType = "2D";
73-
return currentGpuPipelineFor2D;
74-
}
75-
76-
case IImageView<IGPUImage>::ET_2D_ARRAY:
77-
{
78-
viewType = "2D array";
79-
return currentGpuPipelineFor2DArrays;
80-
}
81-
82-
case IImageView<IGPUImage>::ET_CUBE_MAP:
83-
{
84-
viewType = "cube map";
85-
return currentGpuPipelineForCubemaps;
86-
}
87-
88-
default:
89-
{
90-
os::Printer::log("Not supported image view in the example!", ELL_ERROR);
91-
return gpuPipeline();
92-
}
93-
}
94-
};
95-
96-
auto currentGpuPipeline = getCurrentGPUPipeline();
97-
9865
std::wostringstream characterStream;
99-
characterStream << L"Color Space Test Demo - Irrlicht Engine [" << driver->getName() << "] - CURRENT IMAGE: " << currentHandledImageFileName.c_str() << " - VIEW TYPE: " << viewType.c_str() << " - EXTENSION: " << currentHandledImageExtension.c_str();
66+
characterStream << L"Color Space Test Demo - Irrlicht Engine [" << driver->getName() << "] - CURRENT IMAGE: " << currentHandledImageFileName.c_str() << " - EXTENSION: " << currentHandledImageExtension.c_str();
10067
device->setWindowCaption(characterStream.str().c_str());
10168

10269
auto startPoint = std::chrono::high_resolution_clock::now();
@@ -109,8 +76,8 @@ void ApplicationHandler::presentImageOnTheScreen(irr::core::smart_refctd_ptr<irr
10976

11077
driver->beginScene(true, true);
11178

112-
driver->bindGraphicsPipeline(currentGpuPipeline.get());
113-
driver->bindDescriptorSets(EPBP_GRAPHICS, currentGpuPipeline->getLayout(), 3u, 1u, &samplerDescriptorSet3.get(), nullptr);
79+
driver->bindGraphicsPipeline(currentGpuPipelineFor2D.get());
80+
driver->bindDescriptorSets(EPBP_GRAPHICS, currentGpuPipelineFor2D->getLayout(), 3u, 1u, &samplerDescriptorSet3.get(), nullptr);
11481
driver->drawMeshBuffer(currentGpuMeshBuffer.get());
11582

11683
driver->blitRenderTargets(nullptr, screenShotFrameBuffer, false, false);
@@ -122,9 +89,9 @@ void ApplicationHandler::presentImageOnTheScreen(irr::core::smart_refctd_ptr<irr
12289

12390
namespace
12491
{
125-
template<class Kernel>
126-
class MyKernel : public asset::CFloatingPointSeparableImageFilterKernelBase<MyKernel<Kernel>>
127-
{
92+
template<class Kernel>
93+
class MyKernel : public asset::CFloatingPointSeparableImageFilterKernelBase<MyKernel<Kernel>>
94+
{
12895
using Base = asset::CFloatingPointSeparableImageFilterKernelBase<MyKernel<Kernel>>;
12996

13097
Kernel kernel;
@@ -142,11 +109,91 @@ namespace
142109
{
143110
return kernel.weight(x, channel) * multiplier;
144111
}
112+
113+
// we need to ensure to override the default behaviour of `CFloatingPointSeparableImageFilterKernelBase` which applies the weight along every axis
114+
template<class PreFilter, class PostFilter>
115+
struct sample_functor_t
116+
{
117+
sample_functor_t(const MyKernel* _this, PreFilter& _preFilter, PostFilter& _postFilter) :
118+
_this(_this), preFilter(_preFilter), postFilter(_postFilter) {}
119+
120+
inline void operator()(value_type* windowSample, core::vectorSIMDf& relativePos, const core::vectorSIMDi32& globalTexelCoord, const IImageFilterKernel::UserData* userData)
121+
{
122+
preFilter(windowSample, relativePos, globalTexelCoord, userData);
123+
auto* scale = IImageFilterKernel::ScaleFactorUserData::cast(userData);
124+
for (int32_t i=0; i<MaxChannels; i++)
125+
{
126+
// this differs from the `CFloatingPointSeparableImageFilterKernelBase`
127+
windowSample[i] *= _this->weight(relativePos.x, i);
128+
if (scale)
129+
windowSample[i] *= scale->factor[i];
130+
}
131+
postFilter(windowSample, relativePos, globalTexelCoord, userData);
132+
}
133+
134+
private:
135+
const MyKernel* _this;
136+
PreFilter& preFilter;
137+
PostFilter& postFilter;
138+
};
145139

146140
_IRR_STATIC_INLINE_CONSTEXPR bool has_derivative = false;
147141

148142
IRR_DECLARE_DEFINE_CIMAGEFILTER_KERNEL_PASS_THROUGHS(Base)
149-
};
143+
};
144+
145+
template<class Kernel>
146+
class SeparateOutXAxisKernel : public asset::CFloatingPointSeparableImageFilterKernelBase<SeparateOutXAxisKernel<Kernel>>
147+
{
148+
using Base = asset::CFloatingPointSeparableImageFilterKernelBase<SeparateOutXAxisKernel<Kernel>>;
149+
150+
Kernel kernel;
151+
152+
public:
153+
// passthrough everything
154+
using value_type = typename Kernel::value_type;
155+
156+
_IRR_STATIC_INLINE_CONSTEXPR auto MaxChannels = Kernel::MaxChannels; // derivative map only needs 2 channels
157+
158+
SeparateOutXAxisKernel(Kernel&& k) : Base(k.negative_support.x, k.positive_support.x), kernel(std::move(k)) {}
159+
160+
IRR_DECLARE_DEFINE_CIMAGEFILTER_KERNEL_PASS_THROUGHS(Base)
161+
162+
// we need to ensure to override the default behaviour of `CFloatingPointSeparableImageFilterKernelBase` which applies the weight along every axis
163+
template<class PreFilter, class PostFilter>
164+
struct sample_functor_t
165+
{
166+
sample_functor_t(const SeparateOutXAxisKernel<Kernel>* _this, PreFilter& _preFilter, PostFilter& _postFilter) :
167+
_this(_this), preFilter(_preFilter), postFilter(_postFilter) {}
168+
169+
inline void operator()(value_type* windowSample, core::vectorSIMDf& relativePos, const core::vectorSIMDi32& globalTexelCoord, const IImageFilterKernel::UserData* userData)
170+
{
171+
preFilter(windowSample, relativePos, globalTexelCoord, userData);
172+
auto* scale = IImageFilterKernel::ScaleFactorUserData::cast(userData);
173+
for (int32_t i=0; i<MaxChannels; i++)
174+
{
175+
// this differs from the `CFloatingPointSeparableImageFilterKernelBase`
176+
windowSample[i] *= _this->kernel.weight(relativePos.x, i);
177+
if (scale)
178+
windowSample[i] *= scale->factor[i];
179+
}
180+
postFilter(windowSample, relativePos, globalTexelCoord, userData);
181+
}
182+
183+
private:
184+
const SeparateOutXAxisKernel<Kernel>* _this;
185+
PreFilter& preFilter;
186+
PostFilter& postFilter;
187+
};
188+
189+
// the method all kernels must define and overload
190+
template<class PreFilter, class PostFilter>
191+
inline auto create_sample_functor_t(PreFilter& preFilter, PostFilter& postFilter) const
192+
{
193+
return sample_functor_t(this,preFilter,postFilter);
194+
}
195+
};
196+
150197
}
151198
static core::smart_refctd_ptr<asset::ICPUImage> createDerivMapFromHeightMap(asset::ICPUImage* _inImg, asset::ISampler::E_TEXTURE_CLAMP _uwrap, asset::ISampler::E_TEXTURE_CLAMP _vwrap, asset::ISampler::E_TEXTURE_BORDER_COLOR _borderColor)
152199
{
@@ -181,8 +228,10 @@ static core::smart_refctd_ptr<asset::ICPUImage> createDerivMapFromHeightMap(asse
181228
using ReconstructionKernel = CGaussianImageFilterKernel<>; // or Mitchell
182229
using DerivKernel_ = CDerivativeImageFilterKernel<ReconstructionKernel>;
183230
using DerivKernel = MyKernel<DerivKernel_>;
184-
using XDerivKernel = CChannelIndependentImageFilterKernel<DerivKernel, CBoxImageFilterKernel>;
185-
using YDerivKernel = CChannelIndependentImageFilterKernel<CBoxImageFilterKernel, DerivKernel>;
231+
using XDerivKernel_ = CChannelIndependentImageFilterKernel<DerivKernel, CBoxImageFilterKernel>;
232+
using YDerivKernel_ = CChannelIndependentImageFilterKernel<CBoxImageFilterKernel, DerivKernel>;
233+
using XDerivKernel = SeparateOutXAxisKernel<XDerivKernel_>;
234+
using YDerivKernel = SeparateOutXAxisKernel<YDerivKernel_>;
186235
using DerivativeMapFilter = CBlitImageFilter
187236
<
188237
false, false, DefaultSwizzle, IdentityDither, // (Criss, look at impl::CSwizzleAndConvertImageFilterBase)
@@ -193,8 +242,8 @@ static core::smart_refctd_ptr<asset::ICPUImage> createDerivMapFromHeightMap(asse
193242

194243
const auto extent = _inImg->getCreationParameters().extent;
195244
const float mlt = static_cast<float>(std::max(extent.width, extent.height));
196-
XDerivKernel xderiv{ DerivKernel(DerivKernel_(ReconstructionKernel()), mlt), CBoxImageFilterKernel() };
197-
YDerivKernel yderiv{ CBoxImageFilterKernel(), DerivKernel(DerivKernel_(ReconstructionKernel()), mlt) };
245+
XDerivKernel xderiv(XDerivKernel_( DerivKernel(DerivKernel_(ReconstructionKernel()), mlt), CBoxImageFilterKernel() ));
246+
YDerivKernel yderiv(YDerivKernel_( CBoxImageFilterKernel(), DerivKernel(DerivKernel_(ReconstructionKernel()), mlt) ));
198247

199248
using swizzle_t = asset::ICPUImageView::SComponentMapping;
200249
DerivativeMapFilter::state_type state(std::move(xderiv), std::move(yderiv), CBoxImageFilterKernel());
@@ -381,8 +430,6 @@ bool ApplicationHandler::initializeApplication()
381430
};
382431

383432
currentGpuPipelineFor2D = createGPUPipeline(IImageView<ICPUImage>::E_TYPE::ET_2D);
384-
currentGpuPipelineFor2DArrays = createGPUPipeline(IImageView<ICPUImage>::E_TYPE::ET_2D_ARRAY);
385-
currentGpuPipelineForCubemaps = createGPUPipeline(IImageView<ICPUImage>::E_TYPE::ET_CUBE_MAP);
386433

387434
{
388435
SBufferBinding<IGPUBuffer> idxBinding{ 0ull, nullptr };

examples_tests/47.DerivMapTest/ApplicationHandler.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ class ApplicationHandler
3737
irr::core::smart_refctd_ptr<irr::video::IGPUDescriptorSetLayout> gpuDescriptorSetLayout3;
3838

3939
gpuPipeline currentGpuPipelineFor2D;
40-
gpuPipeline currentGpuPipelineFor2DArrays;
41-
gpuPipeline currentGpuPipelineForCubemaps;
4240

4341
irr::video::IFrameBuffer* screenShotFrameBuffer;
4442
irr::core::vector<std::string> imagePaths;
Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,15 @@
1-
; This is the testing suite for various IrrlichtBAW loaders/writers (JPG/PNG/TGA/BMP/DDS/KTX).
1+
; This is the testing suite for various Nabla loaders/writers (JPG/PNG/TGA/BMP/DDS/KTX).
22
; BMP is currently unsupported for now.
33
; 16-bit PNG & 8-bit RLE (compressed) TGA is not supported.
44
; For licensing attribution, see LICENSE.
55

6-
; JPG, colored & 8-bit grayscale
7-
../../media/color_space_test/R8G8B8_1.jpg
8-
../../media/color_space_test/R8G8B8_2.jpg
9-
6+
; JPG, 8-bit grayscale
107
../../media/color_space_test/R8_1.jpg
118
../../media/color_space_test/R8_2.jpg
129

13-
; PNG, 24/32-bit & 8-bit grayscale
14-
../../media/color_space_test/R8G8B8_1.png
15-
../../media/color_space_test/R8G8B8_2.png
16-
../../media/color_space_test/R8G8B8A8_1.png
17-
../../media/color_space_test/R8G8B8A8_2.png
18-
10+
; PNG,8-bit grayscale
1911
../../media/color_space_test/R8_1.png
2012
../../media/color_space_test/R8_2.png
2113

22-
; TGA, 24/32-bit & 8-bit grayscale (+RLE)
23-
../../media/color_space_test/R8G8B8_RLE.tga
24-
25-
../../media/color_space_test/R8G8B8A8.tga
26-
../../media/color_space_test/R8G8B8A8_RLE.tga
27-
14+
; TGA, 8-bit grayscale (+RLE)
2815
../../media/color_space_test/R8.tga

examples_tests/47.DerivMapTest/present2DArray.frag

Lines changed: 0 additions & 13 deletions
This file was deleted.

examples_tests/47.DerivMapTest/presentCubemap.frag

Lines changed: 0 additions & 13 deletions
This file was deleted.

include/irr/asset/filters/CBlitImageFilter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include <algorithm>
1212

1313
#include "irr/asset/filters/CMatchedSizeInOutImageFilterCommon.h"
14-
#include "irr/asset/filters/CSwizzleableAndDitherableFilterBase.h"
14+
#include "irr/asset/filters/CSwizzleAndConvertImageFilter.h"
1515
#include "irr/asset/filters/dithering/CWhiteNoiseDither.h"
1616

1717
#include "irr/asset/filters/kernels/kernels.h"

0 commit comments

Comments
 (0)