Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
PostFXWindow.cpp
Go to the documentation of this file.
1
2
4
5
10
23
24namespace Divide {
25namespace {
26 bool PreviewTextureButton(I32 &id, const Handle<Texture> tex, const bool readOnly)
27 {
28 DIVIDE_ASSERT(tex != INVALID_HANDLE<Texture>);
29
30 bool ret = false;
31 ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - 15);
32 ImGui::PushID(4321234 + id++);
33 if (readOnly)
34 {
36 }
37 if (ImGui::SmallButton("T"))
38 {
39 ret = true;
40 }
41 if (ImGui::IsItemHovered())
42 {
43 ImGui::SetTooltip(Util::StringFormat("Preview texture : {}", Get(tex)->assetName()).c_str());
44 }
45 if (readOnly)
46 {
48 }
49 ImGui::PopID();
50 return ret;
51 }
52
54
55}
56
58 : DockedWindow(parent, descriptor),
60 _postFX(context.gfx().getRenderer().postFX())
61 {
62 }
63
66
68
69 const auto checkBox = [this](const FilterType filter, const char* label = "Enabled", const bool overrideScene = false) {
70 bool filterEnabled = _postFX.getFilterState(filter);
71 ImGui::PushID(to_base(filter));
72 if (ImGui::Checkbox(label, &filterEnabled)) {
73 if (filterEnabled) {
74 _postFX.pushFilter(filter, overrideScene);
75 } else {
76 _postFX.popFilter(filter, overrideScene);
77 }
78 }
79 ImGui::PopID();
80 };
81
82 F32 edgeThreshold = batch.edgeDetectionThreshold();
83 ImGui::AlignTextToFramePadding();
84 ImGui::Text("Edge Threshold: "); ImGui::SameLine();
85
86 ImGui::PushItemWidth(170);
87 {
88 if (ImGui::SliderFloat("##hidelabel", &edgeThreshold, 0.01f, 1.0f)) {
89 batch.edgeDetectionThreshold(edgeThreshold);
90 }
91 }
92 ImGui::PopItemWidth();
93
94 if (ImGui::CollapsingHeader("Fog Settings")) {
95 bool sceneChanged = false;
96 auto& projectManager = context().kernel().projectManager();
97 auto& activeSceneState = projectManager->activeProject()->getActiveScene()->state();
98 bool fogEnabled = context().config().rendering.enableFog;
99 if (ImGui::Checkbox("Enabled", &fogEnabled)) {
100 context().config().rendering.enableFog = fogEnabled;
101 context().config().changed(true);
102 sceneChanged = true;
103 }
104 {
105 F32 fogDensity = activeSceneState->renderState().fogDetails()._colourAndDensity.a;
106 if (ImGui::SliderFloat("Fog Density B", &fogDensity, 0.0001f, 0.25f, "%.6f")) {
107 FogDetails details = activeSceneState->renderState().fogDetails();
108 details._colourAndDensity.a = fogDensity;
109 activeSceneState->renderState().fogDetails(details);
110 sceneChanged = true;
111 }
112 }
113 {
114 F32 fogScatter = activeSceneState->renderState().fogDetails()._colourSunScatter.a;
115 if (ImGui::SliderFloat("Fog Density C", &fogScatter, 0.0001f, 0.25f, "%.6f")) {
116 FogDetails details = activeSceneState->renderState().fogDetails();
117 details._colourSunScatter.a = fogScatter;
118 activeSceneState->renderState().fogDetails(details);
119 sceneChanged = true;
120 }
121 }
122 {
123 FColour3 fogColour = activeSceneState->renderState().fogDetails()._colourAndDensity.rgb;
124 EditorComponentField tempField = {};
125 tempField._name = "[Fog Colour]";
128 tempField._readOnly = false;
129 tempField._data = &fogColour;
130 tempField._format = "%.6f";
131 tempField._range = { 0.0f, 1.0f };
132 tempField._dataSetter = [&](const void* colour) noexcept {
133 FogDetails details = activeSceneState->renderState().fogDetails();
134 details._colourAndDensity.rgb = *static_cast<const FColour3*>(colour);
135 activeSceneState->renderState().fogDetails(details);
136 };
138 sceneChanged = Util::colourInput3(_parent, tempField) || sceneChanged;
140 }
141
142 if (sceneChanged) {
144 }
145 }
146
147 if (ImGui::CollapsingHeader("SS Antialiasing")) {
149 PostAAPreRenderOperator& aaOp = static_cast<PostAAPreRenderOperator&>(*op);
150 I32 level = to_I32(aaOp.postAAQualityLevel());
151
152 ImGui::PushItemWidth(175);
153 {
154 ImGui::AlignTextToFramePadding();
155 ImGui::Text("Quality level: "); ImGui::SameLine();
156 ImGui::PushID("quality_level_slider");
157 if (ImGui::SliderInt("##hidelabel", &level, 0, 5)) {
158 aaOp.postAAQualityLevel(to_U8(level));
159 }
160 ImGui::PopID();
161 }
162 ImGui::PopItemWidth();
163 ImGui::AlignTextToFramePadding();
164 ImGui::Text("Method: "); ImGui::SameLine();
165 static I32 selection = _postFX.getFilterState(FilterType::FILTER_SS_ANTIALIASING) ? (aaOp.useSMAA() ? 0 : 1) : 2;
166 const bool a = ImGui::RadioButton("SMAA", &selection, 0); ImGui::SameLine();
167 const bool b = ImGui::RadioButton("FXAA", &selection, 1); ImGui::SameLine();
168 const bool c = ImGui::RadioButton("NONE", &selection, 2);
169 if (a || b|| c) {
170 if (selection != 2) {
172 aaOp.useSMAA(selection == 0);
173 } else {
175 }
176 }
177 }
178 if (ImGui::CollapsingHeader("SS Ambient Occlusion")) {
181 SSAOPreRenderOperator& ssaoOp = static_cast<SSAOPreRenderOperator&>(*op);
182 F32 radius = ssaoOp.radius();
183 F32 power = ssaoOp.power();
184 F32 bias = ssaoOp.bias();
185 F32 range = ssaoOp.maxRange() * 100.f;
186 F32 fade = ssaoOp.fadeStart() * 100.f;
187 bool halfRes = ssaoOp.genHalfRes();
188
189 if (ImGui::Checkbox("Generate Half Resolution", &halfRes)) {
190 ssaoOp.genHalfRes(halfRes);
191 }
192 if (ImGui::SliderFloat("Radius", &radius, 0.01f, 50.0f)) {
193 ssaoOp.radius(radius);
194 }
195 if (ImGui::SliderFloat("Power", &power, 1.0f, 10.0f)) {
196 ssaoOp.power(power);
197 }
198 if (ImGui::SliderFloat("Bias", &bias, 0.001f, 0.99f)) {
199 ssaoOp.bias(bias);
200 }
201 if (ImGui::SliderFloat("Max Range (%)", &range, 0.001f, 100.f)) {
202 ssaoOp.maxRange(range * 0.01f);
203 }
204 if (ImGui::IsItemHovered()) {
205 ImGui::SetTooltip("100% - Far plane");
206 }
207 if (ImGui::SliderFloat("Fade Start (%)", &fade, 0.001f, 100.f)) {
208 ssaoOp.fadeStart(fade * 0.01f);
209 }
210 if (ImGui::IsItemHovered()) {
211 ImGui::SetTooltip("Applies to the range [0 - Max Range], not to the far plane!");
212 }
213 bool blur = ssaoOp.blurResults();
214 if (ImGui::Checkbox("Blur results", &blur)) {
215 ssaoOp.blurResults(blur);
216 }
217 if (!blur) {
218 PushReadOnly();
219 }
220 F32 blurThreshold = ssaoOp.blurThreshold();
221 if (ImGui::SliderFloat("Blur threshold", &blurThreshold, 0.001f, 0.999f)) {
222 ssaoOp.blurThreshold(blurThreshold);
223 }
224 F32 blurSharpness = ssaoOp.blurSharpness();
225 if (ImGui::SliderFloat("Blur sharpness", &blurSharpness, 0.001f, 128.0f)) {
226 ssaoOp.blurSharpness(blurSharpness);
227 }
228 I32 kernelSize = ssaoOp.blurKernelSize();
229 if (ImGui::SliderInt("Blur kernel size", &kernelSize, 0, 16)) {
230 ssaoOp.blurKernelSize(kernelSize);
231 }
232 if (ImGui::IsItemHovered()) {
233 ImGui::SetTooltip("0 = no blur");
234 }
235 if (!blur) {
236 PopReadOnly();
237 }
238 ImGui::Text("SSAO Sample Count: %d", ssaoOp.sampleCount());
239 }
240 if (ImGui::CollapsingHeader("SS Reflections")) {
242
243 auto& params = context().config().rendering.postFX.ssr;
244 F32& maxDistance = params.maxDistance;
245 F32& jitterAmount = params.jitterAmount;
246 F32& stride = params.stride;
247 F32& zThickness = params.zThickness;
248 F32& strideZCutoff = params.strideZCutoff;
249 F32& screenEdgeFadeStart = params.screenEdgeFadeStart;
250 F32& eyeFadeStart = params.eyeFadeStart;
251 F32& eyeFadeEnd = params.eyeFadeEnd;
252 U16& maxSteps = params.maxSteps;
253 U8& binarySearchIterations = params.binarySearchIterations;
254
255 bool dirty = false;
256 if (ImGui::SliderFloat("Max Distance", &maxDistance, 0.01f, 5000.0f)) {
257 dirty = true;
258 }
259 if (ImGui::SliderFloat("Jitter Ammount", &jitterAmount, 0.01f, 10.0f)) {
260 dirty = true;
261 }
262 if (ImGui::SliderFloat("Stride", &stride, 1.0f, maxSteps)) {
263 dirty = true;
264 }
265 if (ImGui::SliderFloat("Z Thickness", &zThickness, 0.01f, 10.0f)) {
266 dirty = true;
267 }
268 if (ImGui::SliderFloat("Strode Z Cutoff", &strideZCutoff, 0.01f, 1000.0f)) {
269 dirty = true;
270 }
271 if (ImGui::SliderFloat("Screen Edge Fade Start", &screenEdgeFadeStart, 0.01f, 1.0f)) {
272 dirty = true;
273 }
274 if (ImGui::SliderFloat("Eye fade start", &eyeFadeStart, 0.01f, 1.0f)) {
275 dirty = true;
276 }
277 if (ImGui::SliderFloat("Eye fade end", &eyeFadeEnd, eyeFadeStart, 1.0f)) {
278 dirty = true;
279 }
280
281 constexpr U16 stepsMin = 1u;
282 constexpr U16 stepsMax = 1 << 15;
283
284 if (ImGui::SliderScalar("Max Steps", ImGuiDataType_U16, &maxSteps, &stepsMin, &stepsMax)) {
285 dirty = true;
286 }
287 constexpr U8 iterMin = 1u;
288 constexpr U8 iterMax = 1 << 7;
289 if (ImGui::SliderScalar("Binary Search Iterations", ImGuiDataType_U8, &binarySearchIterations, &iterMin, &iterMax)) {
290 dirty = true;
291 }
292
293 if (dirty) {
295 static_cast<SSRPreRenderOperator&>(*op).parametersChanged();
296 context().config().changed(true);
297 }
298 }
299 if (ImGui::CollapsingHeader("Depth of Field")) {
301
302 auto& params = context().config().rendering.postFX.dof;
303
304 bool dirty = false;
305 F32& focalLength = params.focalLength;
306 if (ImGui::SliderFloat("Focal Length (mm)", &focalLength, 0.0f, 100.0f)) {
307 dirty = true;
308 }
309
310 I32 crtStop = to_I32(TypeUtil::StringToFStops(params.fStop));
311 const char* crtStopName = params.fStop.c_str();
312 if (ImGui::SliderInt("FStop", &crtStop, 0, to_base(FStops::COUNT) - 1, crtStopName)) {
313 params.fStop = TypeUtil::FStopsToString(static_cast<FStops>(crtStop));
314 dirty = true;
315 }
316
317 bool& autoFocus = params.autoFocus;
318 if (ImGui::Checkbox("Auto Focus", &autoFocus)) {
319 dirty = true;
320 }
321
322 if (autoFocus) {
323 PushReadOnly();
324 }
325 F32& focalDepth = params.focalDepth;
326 if (ImGui::SliderFloat("Focal Depth (m)", &focalDepth, 0.0f, 100.0f)) {
327 dirty = true;
328 }
329 vec2<F32>& focalPosition = params.focalPoint;
330 if (ImGui::SliderFloat2("Focal Position", focalPosition._v, 0.0f, 1.0f)) {
331 dirty = true;
332 }
333 if (ImGui::IsItemHovered()) {
334 ImGui::SetTooltip("Position of focused point on screen (0.0,0.0 - left lower corner, 1.0,1.0 - upper right)");
335 }
336 if (autoFocus) {
337 PopReadOnly();
338 }
339
340 bool& manualdof = params.manualdof;
341 if (ImGui::Checkbox("Manual dof calculation", &manualdof)) {
342 dirty = true;
343 }
344 if (!manualdof) {
345 PushReadOnly();
346 }
347 F32& ndofstart = params.ndofstart;
348 if (ImGui::SliderFloat("Near dof blur start", &ndofstart, 0.0f, 100.0f)) {
349 dirty = true;
350 }
351 F32& ndofdist = params.ndofdist;
352 if (ImGui::SliderFloat("Near dof blur falloff distance", &ndofdist, 0.0f, 100.0f)) {
353 dirty = true;
354 }
355 F32& fdofstart = params.fdofstart;
356 if (ImGui::SliderFloat("Far dof blur start", &fdofstart, 0.0f, 100.0f)) {
357 dirty = true;
358 }
359 F32& fdofdist = params.fdofdist;
360 if (ImGui::SliderFloat("Far dof blur falloff distance", &fdofdist, 0.0f, 100.0f)) {
361 dirty = true;
362 }
363 if (!manualdof) {
364 PopReadOnly();
365 }
366 bool& vignetting = params.vignetting;
367 if (ImGui::Checkbox("Use optical lens vignetting", &vignetting)) {
368 dirty = true;
369 }
370 if (!vignetting) {
371 PushReadOnly();
372 }
373 F32& vignout = params.vignout;
374 if (ImGui::SliderFloat("Vignetting outer border", &vignout, 0.0f, 100.0f)) {
375 dirty = true;
376 }
377 F32& vignin = params.vignin;
378 if (ImGui::SliderFloat("Vignetting inner border", &vignin, 0.0f, 100.0f)) {
379 dirty = true;
380 }
381 if (!vignetting) {
382 PopReadOnly();
383 }
384
385 bool& debugFocus = params.debugFocus;
386 if (ImGui::Checkbox("Show debug focus point and focal range", &debugFocus)) {
387 dirty = true;
388 }
389 if (ImGui::IsItemHovered()) {
390 ImGui::SetTooltip("red = focal point, green = focal range");
391 }
392
393 if (dirty) {
395 DoFPreRenderOperator& dofOp = static_cast<DoFPreRenderOperator&>(*op);
396 dofOp.parametersChanged();
397 context().config().changed(true);
398 }
399 }
400
401 if (ImGui::CollapsingHeader("Bloom")) {
402 checkBox(FilterType::FILTER_BLOOM);
404 BloomPreRenderOperator& bloomOp = static_cast<BloomPreRenderOperator&>(*op);
405 F32 bias = bloomOp.luminanceBias();
406 if (ImGui::SliderFloat("Luminance Bias", &bias, 0.001f, 0.999f))
407 {
408 bloomOp.luminanceBias(bias);
409 }
410 }
411
412 if (ImGui::CollapsingHeader("Motion Blur")) {
415 MotionBlurPreRenderOperator& blurOP = static_cast<MotionBlurPreRenderOperator&>(*op);
417 if (ImGui::SliderFloat("Veclocity Scale", &velocity, 0.01f, 3.0f)) {
418 blurOP.parametersChanged();
419 _context.config().changed(true);
420 }
421 U8 samples = blurOP.maxSamples(); constexpr U8 min = 1u, max = 16u;
422 if (ImGui::SliderScalar("Max Samples", ImGuiDataType_U8, &samples, &min, &max)) {
423 blurOP.maxSamples(samples);
424 }
425 }
426
427 if (ImGui::CollapsingHeader("Tone Mapping")) {
428 bool adaptiveExposure = batch.adaptiveExposureControl();
429 if (ImGui::Checkbox("Adaptive Exposure", &adaptiveExposure)) {
430 batch.adaptiveExposureControl(adaptiveExposure);
431 }
432
433 bool dirty = false;
434 ToneMapParams params = batch.toneMapParams();
435 if (adaptiveExposure) {
436 if (ImGui::SliderFloat("Min Log Luminance", &params._minLogLuminance, -16.0f, 0.0f)) {
437 dirty = true;
438 }
439 if (ImGui::SliderFloat("Max Log Luminance", &params._maxLogLuminance, 0.0f, 16.0f)) {
440 dirty = true;
441 }
442 if (ImGui::SliderFloat("Tau", &params._tau, 0.1f, 2.0f)) {
443 dirty = true;
444 }
445
446 static I32 exposureRefreshFrameCount = 1;
447 static F32 exposure = 1.0f;
448 if (--exposureRefreshFrameCount == 0) {
449 exposure = batch.adaptiveExposureValue();
450 exposureRefreshFrameCount = g_exposureRefreshFrameCount;
451 }
452
453 ImGui::Text("Current exposure value: %5.2f", exposure);
454 I32 id = 32132131;
455 if (PreviewTextureButton(id, batch.luminanceTex(), false))
456 {
458 }
459 }
460
461 if (ImGui::SliderFloat("Manual exposure", &params._manualExposureFactor, 0.01f, 100.0f)) {
462 dirty = true;
463 }
464
465 I32 crtFunc = to_I32(params._function);
466 const char* crtFuncName = TypeUtil::ToneMapFunctionsToString(params._function);
467 if (ImGui::SliderInt("ToneMap Function", &crtFunc, 0, to_base(ToneMapParams::MapFunctions::COUNT), crtFuncName)) {
468 params._function = static_cast<ToneMapParams::MapFunctions>(crtFunc);
469 dirty = true;
470 }
471
472 if (dirty) {
473 batch.toneMapParams(params);
474 }
475 }
476 if (ImGui::CollapsingHeader("Test Effects")) {
481 }
482
483 if (_previewTexture != INVALID_HANDLE<Texture>)
484 {
485 const string modalName = Util::StringFormat( "Image Preview: {}", Get( _previewTexture )->resourceName() );
487 {
488 _previewTexture = INVALID_HANDLE<Texture>;
489 }
490 }
491 }
492
493} //namespace Divide
#define DIVIDE_ASSERT(...)
#define PROFILE_SCOPE_AUTO(CATEGORY)
Definition: Profiler.h:87
static bool modalTextureView(const Editor &editor, const std::string_view modalName, Handle< Texture > tex, const vec2< F32 > dimensions, const bool preserveAspect, const bool useModal)
Definition: Editor.h:676
static void registerUnsavedSceneChanges(Editor &editor) noexcept
Definition: Editor.h:656
PlatformContext & context() noexcept
Kernel & kernel() noexcept
Editor & editor() noexcept
Configuration & config() noexcept
void popFilter(const FilterType filter, const bool overrideScene=false)
Definition: PostFX.h:94
bool getFilterState(const FilterType filter) const noexcept
Definition: PostFX.h:111
PreRenderBatch & getFilterBatch() noexcept
Definition: PostFX.h:119
void pushFilter(const FilterType filter, const bool overrideScene=false)
Definition: PostFX.h:77
static const char * FilterName(FilterType filter) noexcept
Definition: PostFX.cpp:27
Handle< Texture > _previewTexture
Definition: PostFXWindow.h:50
PostFX & _postFX
Definition: PostFXWindow.h:49
PostFXWindow(Editor &parent, PlatformContext &context, const Descriptor &descriptor)
void drawInternal() override
PreRenderOperator * getOperator(FilterType type) const
void toneMapParams(ToneMapParams params) noexcept
Handle< Texture > luminanceTex() const noexcept
void adaptiveExposureControl(bool state) noexcept
F32 adaptiveExposureValue() const noexcept
vec3< T > rgb
Definition: MathVectors.h:1378
constexpr Optick::Category::Type GUI
Definition: Profiler.h:64
const char * ToneMapFunctionsToString(ToneMapParams::MapFunctions stop) noexcept
FStops StringToFStops(const string &name)
Definition: Camera.cpp:21
const char * FStopsToString(const FStops stop) noexcept
Definition: Camera.cpp:16
Str StringFormat(const char *fmt, Args &&...args)
void PushNarrowLabelWidth()
Definition: Utils.cpp:300
void PopNarrowLabelWidth()
Definition: Utils.cpp:308
bool colourInput3(Editor &parent, EditorComponentField &field)
Definition: Utils.cpp:390
bool PreviewTextureButton(I32 &id, const Handle< Texture > tex, const bool readOnly)
constexpr I32 g_exposureRefreshFrameCount
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
void PushReadOnly(const bool fade)
Definition: Editor.cpp:2961
int32_t I32
uint8_t U8
void PopReadOnly()
Definition: Editor.cpp:2971
Project & parent
Definition: DefaultScene.h:41
uint16_t U16
FStops
Definition: Camera.h:44
constexpr U8 to_U8(const T value)
constexpr I32 to_I32(const T value)
FORCE_INLINE T * Get(const Handle< T > handle)
constexpr auto to_base(const Type value) -> Type
F32 focalLength
F32 velocityScale
F32 maxDistance
struct Divide::Configuration::Rendering::PostFX::DOF dof
struct Divide::Configuration::Rendering::PostFX::MotionBlur motionBlur
struct Divide::Configuration::Rendering::PostFX::SSR ssr
struct Divide::Configuration::Rendering::PostFX postFX
struct Divide::Configuration::Rendering rendering
DELEGATE_STD< void, const void * > _dataSetter
vec2< F32 > _range
Used by slider_type as a min / max range or dropdown as selected_index / count.
EditorComponentFieldType _type
vec4< F32 > _colourAndDensity
Definition: SceneState.h:74
vec4< F32 > _colourSunScatter
Definition: SceneState.h:75
MapFunctions _function