1#include "Foundation/Logging/Logger.h"
2#include "Foundation/Reflection/TypeDatabase.h"
4#include "Components/Core/EnvironmentComponent.h"
6#include "Resources/TextureManager.h"
9#include "ViewContext.h"
10#include "Services/Variables.h"
11#include "Services/Time.h"
13#include "EntityStore.h"
14#include "Systems/Core/EnvironmentSystem.h"
15#include "Rendering/ICapabilities.h"
16#include "Rendering/IGraphicsDevice.h"
18#include "TwinVisualsComponent.h"
19#include "TwinVisualsSystem.h"
27 struct ManagedVariables {
29 bool clearDepth =
true;
30 bool clearColor =
false;
31 float debugView_outline = 1.f;
33 bool renderer_shadowsEnabled =
true;
36 int shadows_cascadeShadowResolution = 1024;
37 StringView shadows_cascadeShadowFormat =
"D16_UNORM";
38 bool postProcess_ambientOcclusion_enabled =
true;
39 StringView postProcess_ambientOcclusion_type =
"SSAO";
40 bool postProcess_autoExposure_enabled =
true;
41 float postProcess_basicAmbientOcclusion_contrast = 2.f;
42 float postProcess_basicAmbientOcclusion_maxScreenRadiusPercentage = 1.5f;
43 float postProcess_basicAmbientOcclusion_resolutionFactor = 2.f;
44 float postProcess_basicAmbientOcclusion_strength = 0.7f;
45 float postProcess_basicAmbientOcclusion_worldSpaceRadius = 0.05f;
46 bool postProcess_bloom_enabled =
true;
47 float postProcess_bloom_intensity = 0.02f;
48 bool postProcess_fxaa_enabled =
true;
49 float postProcess_fxaa_qualityEdgeThreshold = 0.166f;
50 float postProcess_fxaa_qualityEdgeThresholdMin = 0.0833f;
51 float postProcess_fxaa_qualitySubpix = 0.5f;
52 bool postProcess_multiSampleForwardPass =
false;
53 int postProcess_HBAO_dirCount = 5;
54 float postProcess_HBAO_power = 1.2f;
55 int postProcess_HBAO_stepsPerDir = 15;
56 float postProcess_HBAO_strength = 0.8f;
57 float postProcess_HBAO_contrast = 0.8f;
58 float postProcess_HBAO_worldSpaceRadius = 50.f;
59 float postProcess_HBAO_maxScreenRadiusPercentage = 15.f;
60 float postProcess_HBAO_thicknessWS = 1.f;
61 float renderer_exposureCompensation = 0.f;
62 float renderer_exposureDecreaseSpeed = 50.f;
63 float renderer_exposureIncreaseSpeed = 100.f;
64 int postProcess_autoExposure_updateInterval = 10;
65 float postProcess_autoExposure_sampleArea_x = 0.3f;
66 float postProcess_autoExposure_sampleArea_y = 0.3f;
67 float renderer_exposureMaximum = 10.f;
68 float renderer_exposureMinimum = 0.00000001f;
69 float renderer_lightScale = 1.f;
70 float renderer_maxShadowDistance = 30000.f;
71 float renderer_UpscaleHeight = 1.0;
72 float renderer_UpscaleWidth = 1.0;
73 float renderer_postProcess_blur_radius = 8.f;
74 bool renderer_postProcess_depthOfField_enabled =
false;
75 float renderer_postProcess_depthOfField_startDistance = 50.f;
76 float renderer_postProcess_depthOfField_smoothing = 1000.f;
77 int renderer_samples = 4;
78 bool twinVisuals_highlightRegions_enabled =
false;
79 bool twinVisuals_groundPlane_enabled =
false;
80 bool renderer_multiSampleForwardPass =
true;
83 void setVariables(
Context* context,
const ManagedVariables& variables)
85 context->
variables->set(
"renderer.pipeline", variables.pipeline);
86 context->
variables->set(
"renderer.filterPermutation", variables.renderer_filterPermutation);
87 context->
variables->set(
"clearColor", variables.clearColor);
88 context->
variables->set(
"clearDepth", variables.clearDepth);
89 context->
variables->set(
"debugView.outline", variables.debugView_outline);
90 context->
variables->set(
"renderer.tonemapper", variables.renderer_tonemapper);
91 context->
variables->set(
"renderer.shadowsEnabled", variables.renderer_shadowsEnabled);
92 context->
variables->set(
"shadows.softShadows", variables.shadows_softShadows);
93 context->
variables->set(
"shadows.cascadeShadowResolution", variables.shadows_cascadeShadowResolution);
94 context->
variables->set(
"shadows.cascadeShadowFormat", variables.shadows_cascadeShadowFormat);
95 context->
variables->set(
"postProcess.ambientOcclusion.enabled", variables.postProcess_ambientOcclusion_enabled);
96 context->
variables->set(
"postProcess.ambientOcclusion.type", variables.postProcess_ambientOcclusion_type);
97 context->
variables->set(
"postProcess.autoExposure.enabled", variables.postProcess_autoExposure_enabled);
98 context->
variables->set(
"postProcess.basicAmbientOcclusion.contrast", variables.postProcess_basicAmbientOcclusion_contrast);
99 context->
variables->set(
"postProcess.basicAmbientOcclusion.maxScreenRadiusPercentage", variables.postProcess_basicAmbientOcclusion_maxScreenRadiusPercentage);
100 context->
variables->set(
"postProcess.basicAmbientOcclusion.resolutionFactor", variables.postProcess_basicAmbientOcclusion_resolutionFactor);
101 context->
variables->set(
"postProcess.basicAmbientOcclusion.strength", variables.postProcess_basicAmbientOcclusion_strength);
102 context->
variables->set(
"postProcess.basicAmbientOcclusion.worldSpaceRadius", variables.postProcess_basicAmbientOcclusion_worldSpaceRadius);
103 context->
variables->set(
"postProcess.bloom.enabled", variables.postProcess_bloom_enabled);
104 context->
variables->set(
"postProcess.fxaa.enabled", variables.postProcess_fxaa_enabled);
105 context->
variables->set(
"postProcess.fxaa.qualityEdgeThreshold", variables.postProcess_fxaa_qualityEdgeThreshold);
106 context->
variables->set(
"postProcess.fxaa.qualityEdgeThresholdMin", variables.postProcess_fxaa_qualityEdgeThresholdMin);
107 context->
variables->set(
"postProcess.fxaa.qualitySubpix", variables.postProcess_fxaa_qualitySubpix);
108 context->
variables->set(
"postProcess.HBAO.dirCount", variables.postProcess_HBAO_dirCount);
109 context->
variables->set(
"postProcess.HBAO.power", variables.postProcess_HBAO_power);
110 context->
variables->set(
"postProcess.HBAO.stepsPerDir", variables.postProcess_HBAO_stepsPerDir);
111 context->
variables->set(
"postProcess.HBAO.strength", variables.postProcess_HBAO_strength);
112 context->
variables->set(
"postProcess.HBAO.contrast", variables.postProcess_HBAO_contrast);
113 context->
variables->set(
"postProcess.HBAO.worldSpaceRadius", variables.postProcess_HBAO_worldSpaceRadius);
114 context->
variables->set(
"postProcess.HBAO.maxScreenRadiusPercentage", variables.postProcess_HBAO_maxScreenRadiusPercentage);
115 context->
variables->set(
"postProcess.HBAO.thicknessWS", variables.postProcess_HBAO_thicknessWS);
116 context->
variables->set(
"postProcess.multiSampleForwardPass", variables.postProcess_multiSampleForwardPass);
117 context->
variables->set(
"renderer.exposureCompensation", variables.renderer_exposureCompensation);
118 context->
variables->set(
"renderer.exposureDecreaseSpeed", variables.renderer_exposureDecreaseSpeed);
119 context->
variables->set(
"renderer.exposureIncreaseSpeed", variables.renderer_exposureIncreaseSpeed);
120 context->
variables->set(
"renderer.UpscaleHeight", variables.renderer_UpscaleHeight);
121 context->
variables->set(
"renderer.UpscaleWidth", variables.renderer_UpscaleWidth);
122 context->
variables->set(
"renderer.postProcess.autoExposure.updateInterval", variables.postProcess_autoExposure_updateInterval);
123 context->
variables->set(
"renderer.postProcess.autoExposure.sampleArea_x", variables.postProcess_autoExposure_sampleArea_x);
124 context->
variables->set(
"renderer.postProcess.autoExposure.sampleArea_y", variables.postProcess_autoExposure_sampleArea_y);
125 context->
variables->set(
"renderer.exposureMaximum", variables.renderer_exposureMaximum);
126 context->
variables->set(
"renderer.exposureMinimum", variables.renderer_exposureMinimum);
127 context->
variables->set(
"renderer.lightScale", variables.renderer_lightScale);
128 context->
variables->set(
"renderer.maxShadowDistance", variables.renderer_maxShadowDistance);
129 context->
variables->set(
"renderer.postProcess.blur.radius", variables.renderer_postProcess_blur_radius);
130 context->
variables->set(
"renderer.postProcess.depthOfField.enabled", variables.renderer_postProcess_depthOfField_enabled);
131 context->
variables->set(
"renderer.postProcess.depthOfField.smoothing", variables.renderer_postProcess_depthOfField_smoothing);
132 context->
variables->set(
"renderer.postProcess.depthOfField.startDistance", variables.renderer_postProcess_depthOfField_startDistance);
133 context->
variables->set(
"renderer.samples", variables.renderer_samples);
134 context->
variables->set(
"twinVisuals.highlightRegions.enabled", variables.twinVisuals_highlightRegions_enabled);
135 context->
variables->set(
"twinVisuals.groundPlane.enabled", variables.twinVisuals_groundPlane_enabled);
136 context->
variables->set(
"renderer.multiSampleForwardPass", variables.renderer_multiSampleForwardPass);
146 if (visualsComp.hasChanged()) {
149 if (visualsData.biosphere != visualsComp.biosphere) {
150 visualsData.biosphere = visualsComp.biosphere;
151 if (visualsData.biosphere.empty()) {
152 visualsData.ggx.clear(
context, visualsData);
153 visualsData.lut.clear(
context, visualsData);
154 visualsData.lambertian.clear(
context, visualsData);
155 visualsData.skybox.clear(
context, visualsData);
158 visualsData.ggx.issue(
context, visualsData, visualsData.biosphere +
"/GGX.ktx2");
159 visualsData.lut.issue(
context, visualsData, visualsData.biosphere +
"/LUT.png");
160 visualsData.lambertian.issue(
context, visualsData, visualsData.biosphere +
"/Lambertian.ktx2");
161 visualsData.skybox.issue(
context, visualsData, visualsData.biosphere +
"/skybox.ktx2");
170 bool forceUpdate =
false;
176 bool update = forceUpdate || visualsData.firstrun;
177 visualsData.firstrun =
false;
180 const TwinVisualsDynamicRenderResolution drrPreset = visualsComp.dynamicRenderResolution;
181 const bool useLowResolution = visualsComp.useLowResolution && drrPreset != TwinVisualsDynamicRenderResolution::FullQuality;
186 bool highlightRegionEnable =
false;
187 if (visualsComp.highlightRegionEnable) {
190 if (system->pool.size()) {
191 highlightRegionEnable =
true;
198 if (visualsComp.mode == TwinVisualsMode::Advanced || visualsComp.mode == TwinVisualsMode::DarkFocus || visualsComp.mode == TwinVisualsMode::SurfaceDarkFocus) {
199 uint32_t framesSinceDirty = context->
time->getFrame() - context->
engine->getLastDirtyFrame();
200 if (framesSinceDirty <= 60) {
201 context->
engine->triggerUpdate();
205 bool pbrEnvironmentEnabled =
false;
208 pbrEnvironmentEnabled = env->PBR;
210 bool enableGroundPlane = visualsComp.groundPlaneEnabled;
213 || (visualsData.mode != visualsComp.mode)
214 || (visualsData.texAtlasStyle != visualsComp.texAtlasStyle)
215 || (visualsData.qualityPreset != visualsComp.qualityPreset)
216 || (visualsData.tonemapper != visualsComp.tonemapper)
217 || (visualsData.shadowsEnabled != visualsComp.shadowsEnabled)
218 || (visualsData.highlightRegionEnabled != highlightRegionEnable)
219 || (visualsData.pbrEnvironmentEnabled != pbrEnvironmentEnabled)
220 || (visualsData.drrPreset != drrPreset)
221 || (visualsData.useLowRes != useLowResolution)
222 || (visualsData.brightness != visualsComp.brightness)
223 || (visualsData.groundPlaneEnabled != enableGroundPlane);
225 visualsData.tonemapper = visualsComp.tonemapper;
226 visualsData.shadowsEnabled = visualsComp.shadowsEnabled;
227 visualsData.drrPreset = drrPreset;
228 visualsData.useLowRes = useLowResolution;
229 visualsData.highlightRegionEnabled = highlightRegionEnable;
230 visualsData.mode = visualsComp.mode;
231 visualsData.texAtlasStyle = visualsComp.texAtlasStyle;
232 visualsData.qualityPreset = visualsComp.qualityPreset;
233 visualsData.pbrEnvironmentEnabled = pbrEnvironmentEnabled;
234 visualsData.brightness = visualsComp.brightness;
235 visualsData.groundPlaneEnabled = enableGroundPlane;
236 float upscaleFactor = 1.f;
238 case TwinVisualsDynamicRenderResolution::FullQuality:
241 case TwinVisualsDynamicRenderResolution::Balanced:
242 upscaleFactor = useLowResolution ? 4.f / 3.f : 1.f;
244 case TwinVisualsDynamicRenderResolution::Fast:
245 upscaleFactor = useLowResolution ? 16.f / 9.f : 4.f / 3.f;
247 case TwinVisualsDynamicRenderResolution::FullAndSmooth:
248 upscaleFactor = useLowResolution ? 19.f / 9.f : 1.f;
255 ManagedVariables variables;
256 variables.twinVisuals_groundPlane_enabled = enableGroundPlane;
257 if (context->device->getCapabilities()->getDeviceCapabilities().MaxSamples == 1) {
258 variables.renderer_multiSampleForwardPass =
false;
260 variables.renderer_shadowsEnabled = visualsData.shadowsEnabled;
261 variables.renderer_UpscaleHeight = upscaleFactor;
262 variables.renderer_UpscaleWidth = upscaleFactor;
263 variables.twinVisuals_highlightRegions_enabled = visualsData.highlightRegionEnabled;
264 switch (visualsComp.mode) {
265 case TwinVisualsMode::Balanced:
268 if(visualsComp.groundPlaneEnabled) {
269 variables.pipeline =
"TwinVisuals/Pipelines/TexAtlas/BalancedWithTexAtlas.pipeline";
272 variables.pipeline =
"TwinVisuals/Pipelines/Balanced/Balanced.pipeline";
274 variables.clearDepth =
true;
275 variables.clearColor =
false;
276 variables.renderer_maxShadowDistance = 150.f;
277 variables.shadows_softShadows =
"Low";
280 case TwinVisualsMode::Advanced:
281 variables.pipeline =
"TwinVisuals/Pipelines/Advanced/Advanced.pipeline";
282 variables.clearDepth =
true;
283 variables.clearColor =
false;
284 variables.postProcess_ambientOcclusion_enabled =
true;
285 variables.postProcess_autoExposure_enabled =
false;
286 variables.postProcess_basicAmbientOcclusion_contrast = 0.9f;
287 variables.postProcess_basicAmbientOcclusion_maxScreenRadiusPercentage = 0.6f;
288 variables.postProcess_basicAmbientOcclusion_resolutionFactor = 1.f;
289 variables.postProcess_basicAmbientOcclusion_strength = 0.7f;
290 variables.postProcess_basicAmbientOcclusion_worldSpaceRadius = 50.f;
291 variables.postProcess_HBAO_dirCount = 3;
292 variables.postProcess_HBAO_power = 3;
293 variables.postProcess_HBAO_stepsPerDir = 20;
295 variables.postProcess_bloom_enabled =
true;
296 variables.postProcess_bloom_intensity = 0.005f;
297 variables.postProcess_fxaa_enabled =
true;
298 variables.postProcess_fxaa_qualityEdgeThreshold = 0.063f;
299 variables.postProcess_fxaa_qualityEdgeThresholdMin = 0.0312f;
300 variables.postProcess_fxaa_qualitySubpix = 1.f;
301 variables.postProcess_multiSampleForwardPass =
true;
302 variables.renderer_exposureDecreaseSpeed = 6.f;
303 variables.renderer_exposureIncreaseSpeed = 6.f;
304 variables.renderer_exposureMaximum = 8.f;
305 variables.renderer_exposureMinimum = 0.3f;
306 variables.renderer_lightScale = 0.5f + visualsData.brightness;
307 variables.renderer_maxShadowDistance = 150.f;
308 variables.shadows_softShadows =
"Low";
309 variables.renderer_samples = 8;
312 case TwinVisualsMode::Glass:
313 variables.pipeline =
"TwinVisuals/Pipelines/Glass/GlassMode.pipeline";
314 variables.clearDepth =
true;
315 variables.clearColor =
false;
316 variables.renderer_lightScale = 0.5f + visualsData.brightness;
319 case TwinVisualsMode::Sketch:
320 variables.pipeline =
"TwinVisuals/Pipelines/Sketch/BasicNPRUpscale.pipeline";
321 variables.clearDepth =
true;
322 variables.clearColor =
false;
323 variables.renderer_lightScale = 0.5f + visualsData.brightness;
326 case TwinVisualsMode::DepthOfField:
327 variables.pipeline = drrPreset == TwinVisualsDynamicRenderResolution::FullQuality ?
"Pipelines/DepthOfField/UseDepthOfField.pipeline" :
"Pipelines/DepthOfField/UseDepthOfFieldUpscale.pipeline";
328 variables.renderer_postProcess_depthOfField_enabled =
true;
329 variables.renderer_postProcess_blur_radius = 5.f;
330 variables.renderer_postProcess_depthOfField_smoothing = 50.f;
331 variables.renderer_postProcess_depthOfField_startDistance = 10.f;
332 variables.renderer_lightScale = 0.5f + visualsData.brightness;
335 case TwinVisualsMode::Preview3DTriangleSize:
336 variables.pipeline =
"Pipelines/DebugView/ShowTriangleSizes.pipeline";
337 variables.debugView_outline = 0.f;
340 case TwinVisualsMode::DarkFocus:
341 variables.pipeline =
"TwinVisuals/Pipelines/Advanced/Advanced.pipeline";
342 variables.clearDepth =
true;
343 variables.clearColor =
false;
344 variables.postProcess_ambientOcclusion_enabled =
true;
345 variables.postProcess_ambientOcclusion_type =
"SSAO";
346 variables.postProcess_autoExposure_enabled =
true;
347 variables.postProcess_basicAmbientOcclusion_contrast = 0.9f;
348 variables.postProcess_basicAmbientOcclusion_maxScreenRadiusPercentage = 5.0f;
349 variables.postProcess_basicAmbientOcclusion_resolutionFactor = 1.f;
350 variables.postProcess_basicAmbientOcclusion_strength = 1.0f;
351 variables.postProcess_basicAmbientOcclusion_worldSpaceRadius = 50.f;
352 variables.postProcess_bloom_enabled =
true;
353 variables.postProcess_bloom_intensity = 0.007f;
354 variables.postProcess_fxaa_enabled =
true;
355 variables.postProcess_fxaa_qualityEdgeThreshold = 0.063f;
356 variables.postProcess_fxaa_qualityEdgeThresholdMin = 0.0312f;
357 variables.postProcess_fxaa_qualitySubpix = 1.f;
358 variables.postProcess_multiSampleForwardPass =
true;
359 variables.renderer_exposureCompensation = 4.f* visualsData.brightness - 2.f;
360 variables.renderer_exposureDecreaseSpeed = 6.f;
361 variables.renderer_exposureIncreaseSpeed = 6.f;
362 variables.renderer_exposureMaximum = 2.5f;
363 variables.renderer_exposureMinimum = 0.3f;
364 variables.renderer_lightScale = 1.f;
365 variables.renderer_maxShadowDistance = 150.f;
366 variables.renderer_samples = 8;
367 variables.shadows_softShadows =
"Low";
368 variables.shadows_cascadeShadowResolution = 4096;
371 case TwinVisualsMode::SurfaceCAD:
372 variables.pipeline =
"TwinVisuals/Pipelines/Surface/Surface.pipeline";
373 variables.clearDepth =
true;
374 variables.clearColor =
false;
375 variables.postProcess_ambientOcclusion_enabled =
true;
376 variables.postProcess_ambientOcclusion_type =
"SSAO";
377 variables.postProcess_autoExposure_enabled =
false;
378 variables.postProcess_basicAmbientOcclusion_contrast = 0.9f;
379 variables.postProcess_basicAmbientOcclusion_maxScreenRadiusPercentage = 0.6f;
380 variables.postProcess_basicAmbientOcclusion_resolutionFactor = 1.f;
381 variables.postProcess_basicAmbientOcclusion_strength = 0.7f;
382 variables.postProcess_basicAmbientOcclusion_worldSpaceRadius = 50.f;
383 variables.postProcess_bloom_enabled =
false;
384 variables.postProcess_fxaa_enabled =
true;
385 variables.postProcess_fxaa_qualityEdgeThreshold = 0.063f;
386 variables.postProcess_fxaa_qualityEdgeThresholdMin = 0.0312f;
387 variables.postProcess_fxaa_qualitySubpix = 1.f;
388 variables.postProcess_multiSampleForwardPass =
true;
389 variables.renderer_maxShadowDistance = 150.f;
390 variables.shadows_softShadows =
"Low";
391 variables.renderer_samples = 4;
392 variables.renderer_lightScale = 0.5f + visualsData.brightness;
395 case TwinVisualsMode::SurfaceDefault:
396 variables.pipeline =
"TwinVisuals/Pipelines/Surface/Surface.pipeline";
397 variables.clearDepth =
true;
398 variables.clearColor =
false;
399 variables.postProcess_ambientOcclusion_enabled =
true;
400 variables.postProcess_ambientOcclusion_type =
"HBAO";
401 variables.postProcess_autoExposure_enabled =
false;
402 variables.postProcess_basicAmbientOcclusion_contrast = 0.9f;
403 variables.postProcess_basicAmbientOcclusion_maxScreenRadiusPercentage = 0.6f;
404 variables.postProcess_basicAmbientOcclusion_resolutionFactor = 1.f;
405 variables.postProcess_basicAmbientOcclusion_strength = 0.7f;
406 variables.postProcess_basicAmbientOcclusion_worldSpaceRadius = 50.f;
407 variables.postProcess_HBAO_dirCount = useLowResolution ? 3 : 5;
408 variables.postProcess_HBAO_power = 3;
409 variables.postProcess_HBAO_stepsPerDir = useLowResolution ? 15 : 25;
411 variables.postProcess_bloom_enabled =
true;
412 variables.postProcess_bloom_intensity = 0.005f;
413 variables.postProcess_fxaa_enabled =
true;
414 variables.postProcess_fxaa_qualityEdgeThreshold = 0.063f;
415 variables.postProcess_fxaa_qualityEdgeThresholdMin = 0.0312f;
416 variables.postProcess_fxaa_qualitySubpix = 1.f;
417 variables.postProcess_multiSampleForwardPass =
true;
418 variables.renderer_exposureDecreaseSpeed = 6.f;
419 variables.renderer_exposureIncreaseSpeed = 6.f;
420 variables.renderer_exposureMaximum = 8.f;
421 variables.renderer_exposureMinimum = 0.3f;
422 variables.renderer_lightScale = 0.5f + visualsData.brightness;
423 variables.renderer_maxShadowDistance = 150.f;
424 variables.shadows_softShadows =
"Low";
425 variables.renderer_samples = 8;
428 case TwinVisualsMode::SurfaceHyper:
429 variables.pipeline =
"TwinVisuals/Pipelines/Surface/Surface.pipeline";
430 variables.clearDepth =
true;
431 variables.clearColor =
false;
432 variables.postProcess_ambientOcclusion_enabled =
true;
433 variables.postProcess_ambientOcclusion_type =
"HBAO";
434 variables.postProcess_autoExposure_enabled =
false;
435 variables.postProcess_basicAmbientOcclusion_contrast = 0.9f;
436 variables.postProcess_basicAmbientOcclusion_maxScreenRadiusPercentage = 5.0f;
437 variables.postProcess_basicAmbientOcclusion_resolutionFactor = 1.f;
438 variables.postProcess_basicAmbientOcclusion_strength = 1.0f;
439 variables.postProcess_basicAmbientOcclusion_worldSpaceRadius = 50.f;
440 variables.postProcess_bloom_enabled =
true;
441 variables.postProcess_fxaa_enabled =
true;
442 variables.postProcess_fxaa_qualityEdgeThreshold = 0.063f;
443 variables.postProcess_fxaa_qualityEdgeThresholdMin = 0.0312f;
444 variables.postProcess_fxaa_qualitySubpix = 1.f;
445 variables.postProcess_HBAO_dirCount = 5;
446 variables.postProcess_HBAO_stepsPerDir = 25;
447 variables.postProcess_HBAO_power = 3.0f;
448 variables.postProcess_HBAO_strength = 0.7f;
449 variables.postProcess_HBAO_contrast = 0.7f;
450 variables.postProcess_multiSampleForwardPass =
true;
451 variables.renderer_lightScale = 0.5f + visualsData.brightness;
452 variables.renderer_maxShadowDistance = 150.f;
453 variables.renderer_samples = 8;
454 variables.shadows_softShadows =
"Low";
455 variables.shadows_cascadeShadowResolution = 4096;
458 case TwinVisualsMode::SurfaceGlass:
459 variables.pipeline =
"TwinVisuals/Pipelines/Surface/SurfaceGlass.pipeline";
460 variables.clearDepth =
true;
461 variables.clearColor =
false;
462 variables.renderer_lightScale = 0.5f + visualsData.brightness;
465 case TwinVisualsMode::SurfaceSketch:
466 variables.pipeline =
"TwinVisuals/Pipelines/Surface/SurfaceSketch.pipeline";
467 variables.clearDepth =
true;
468 variables.clearColor =
false;
469 variables.renderer_lightScale = 0.5f + visualsData.brightness;
472 case TwinVisualsMode::SurfaceDarkFocus:
473 variables.pipeline =
"TwinVisuals/Pipelines/Surface/Surface.pipeline";
474 variables.clearDepth =
true;
475 variables.clearColor =
false;
476 variables.postProcess_ambientOcclusion_enabled =
true;
477 variables.postProcess_ambientOcclusion_type =
"SSAO";
478 variables.postProcess_autoExposure_enabled =
false;
479 variables.postProcess_basicAmbientOcclusion_contrast = 0.9f;
480 variables.postProcess_basicAmbientOcclusion_maxScreenRadiusPercentage = 5.0f;
481 variables.postProcess_basicAmbientOcclusion_resolutionFactor = 1.f;
482 variables.postProcess_basicAmbientOcclusion_strength = 1.0f;
483 variables.postProcess_basicAmbientOcclusion_worldSpaceRadius = 50.f;
484 variables.postProcess_bloom_enabled =
true;
485 variables.postProcess_bloom_intensity = 0.007f;
486 variables.postProcess_fxaa_enabled =
true;
487 variables.postProcess_fxaa_qualityEdgeThreshold = 0.063f;
488 variables.postProcess_fxaa_qualityEdgeThresholdMin = 0.0312f;
489 variables.postProcess_fxaa_qualitySubpix = 1.f;
490 variables.postProcess_multiSampleForwardPass =
true;
491 variables.renderer_exposureCompensation = 4.f* visualsData.brightness - 2.f;
492 variables.renderer_exposureDecreaseSpeed = 6.f;
493 variables.renderer_exposureIncreaseSpeed = 6.f;
494 variables.renderer_exposureMaximum = 2.5f;
495 variables.renderer_exposureMinimum = 0.3f;
496 variables.renderer_lightScale = 1.f;
497 variables.renderer_maxShadowDistance = 150.f;
498 variables.renderer_samples = 8;
499 variables.shadows_softShadows =
"Low";
500 variables.shadows_cascadeShadowResolution = 4096;
502 case TwinVisualsMode::SurfaceClay:
503 variables.pipeline =
"TwinVisuals/Pipelines/Surface/Clay.pipeline";
504 variables.clearDepth =
true;
505 variables.clearColor =
false;
506 variables.postProcess_ambientOcclusion_enabled =
true;
507 variables.postProcess_ambientOcclusion_type =
"HBAO";
508 variables.postProcess_ambientOcclusion_enabled =
true;
509 variables.postProcess_autoExposure_enabled =
false;
510 variables.postProcess_bloom_enabled =
false;
511 variables.postProcess_fxaa_enabled =
true;
512 variables.postProcess_fxaa_qualityEdgeThreshold = 0.063f;
513 variables.postProcess_fxaa_qualityEdgeThresholdMin = 0.0312f;
514 variables.postProcess_fxaa_qualitySubpix = 1.f;
515 variables.postProcess_multiSampleForwardPass =
true;
518 float x = std::max(0.0f, std::min(1.0f, visualsData.brightness));
521 variables.renderer_lightScale = 1.8f * x + 0.1f;
525 variables.renderer_lightScale = 6.f * x - 2.f;
528 variables.renderer_maxShadowDistance = 150.f;
529 variables.renderer_samples = 4;
530 variables.shadows_softShadows =
"Low";
531 variables.shadows_cascadeShadowResolution = 256;
532 switch (visualsComp.qualityPreset) {
533 case TwinVisualsQualityPreset::Low:
534 variables.pipeline =
"TwinVisuals/Pipelines/Surface/ClayLow.pipeline";
535 variables.postProcess_ambientOcclusion_type =
"HBAOv2";
536 variables.renderer_shadowsEnabled =
false;
537 variables.postProcess_ambientOcclusion_enabled =
true;
538 variables.postProcess_fxaa_enabled =
false;
540 case TwinVisualsQualityPreset::Medium:
541 variables.renderer_shadowsEnabled =
false;
542 variables.postProcess_HBAO_dirCount = 4;
543 variables.postProcess_HBAO_power = 1.75;
544 variables.postProcess_HBAO_stepsPerDir = 7;
545 variables.postProcess_HBAO_strength = 0.75;
546 variables.postProcess_HBAO_thicknessWS = 6;
547 variables.postProcess_HBAO_maxScreenRadiusPercentage = 3.0;
549 case TwinVisualsQualityPreset::High:
550 variables.postProcess_HBAO_dirCount = 5;
551 variables.postProcess_HBAO_power = 3;
552 variables.postProcess_HBAO_stepsPerDir = 30;
553 variables.postProcess_HBAO_strength = 0.8f;
554 variables.postProcess_HBAO_thicknessWS = 1.0;
555 variables.shadows_cascadeShadowResolution = 2048;
557 case TwinVisualsQualityPreset::Ultra:
558 variables.postProcess_HBAO_dirCount = 7;
559 variables.postProcess_HBAO_power = 3;
560 variables.postProcess_HBAO_stepsPerDir = 30;
561 variables.postProcess_HBAO_strength = 0.8f;
562 variables.postProcess_HBAO_thicknessWS = 1.0f;
563 variables.shadows_softShadows =
"High";
564 variables.shadows_cascadeShadowResolution = 4096;
567 assert(
false &&
"Invalid enum value");
570 variables.renderer_filterPermutation = variables.postProcess_ambientOcclusion_type ==
"HBAOv2" ?
"ForwardWithStructureBuffer" :
"ForwardWithNormals";
576 assert(
false &&
"Invalid enum value");
579 variables.postProcess_bloom_intensity /= (upscaleFactor * upscaleFactor);
580 switch (visualsComp.tonemapper) {
581 case TwinVisualsTonemapper::Reinhard:
582 variables.renderer_tonemapper =
"Reinhard";
584 case TwinVisualsTonemapper::Filmic:
585 variables.renderer_tonemapper =
"Filmic";
587 case TwinVisualsTonemapper::ACESLuminance:
588 variables.renderer_tonemapper =
"ACESLuminance";
590 case TwinVisualsTonemapper::PBRNeutral:
591 variables.renderer_tonemapper =
"PBRNeutral";
594 assert(
false &&
"Invalid enum value");
598 setVariables(context, variables);
602 visualsData.ggx.check(context, visualsData);
603 visualsData.lut.check(context, visualsData);
604 visualsData.lambertian.check(context, visualsData);
605 visualsData.skybox.check(context, visualsData);
608 if (visualsData.presentTextures) {
609 if (
EnvironmentComponent* envComp = context->environmentSystem->getGlobalEnvironment(); envComp) {
610 envComp->radiance = visualsData.ggx.present;
611 envComp->irradiance = visualsData.lambertian.present;
612 envComp->brdfLUT = visualsData.lut.present;
613 envComp->skyDome = visualsData.skybox.present;
625 visualsData.presentTextures =
false;
626 if (visualsData.prevTextureLoadingState != visualsData.currTextureLoadingState) {
627 switch (visualsData.currTextureLoadingState) {
628 case TextureLoadingState::Ready:
629 visualsData.presentTextures =
true;
630 context->
engine->triggerUpdate();
633 case TextureLoadingState::Loading:
634 context->
engine->invokeComponentNotifyCallback(visualsComp, (
int)TwinVisualsNotification::TexturesLoading,
nullptr, 0);
636 case TextureLoadingState::Failed:
642 visualsData.prevTextureLoadingState = visualsData.currTextureLoadingState;
643 visualsData.currTextureLoadingState = TextureLoadingState::Ready;
650 if (globalTwinVisualsComponent ==
nullptr) {
659 globalTwinVisualsComponent =
nullptr;
661 base::destroyComponent(handle);
668 if (visualsData.currTextureLoadingState != TextureLoadingState::Failed) {
669 visualsData.currTextureLoadingState = TextureLoadingState::Loading;
676 LOG_DEBUG(logger,
"Frame %u: Issue fetch for %.*s", context->
time->getFrame(), StringViewFormat(issued->getSource()));
677 if (visualsData.currTextureLoadingState != TextureLoadingState::Failed) {
678 visualsData.currTextureLoadingState = TextureLoadingState::Loading;
685 if (issued->hasFailedLoad()) {
686 visualsData.currTextureLoadingState = TextureLoadingState::Failed;
688 else if (!issued->isResident()) {
689 if (visualsData.currTextureLoadingState != TextureLoadingState::Failed) {
690 visualsData.currTextureLoadingState = TextureLoadingState::Loading;
693 else if(present != issued) {
695 LOG_DEBUG(logger,
"Frame %u: Resident texture %.*s", context->
time->getFrame(), StringViewFormat(issued->getSource()));
698 return visualsData.presentTextures;
Context * context
Pointer to the Context instance the system lives in.
void postUpdate()
Perform post update logic in the system.
void update()
Updates the system state to that of the current frame.
void preUpdate()
Run the pre-update method of the system.
Typed component system managing a pool of components with the given ComponentType.
ComponentPool< ComponentType > pool
Pool of components managed by the system.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
class ComponentSystemBase * getExtensionSystem(const uint16_t id)
Retrieve the system with the given id.
std::unique_ptr< class Variables > variables
Variables service instance.
std::unique_ptr< class Time > time
Time service instance.
std::unique_ptr< class Engine > engine
Engine instance.
Log implementation class.
static const Type & getType()
Get the Type of the given template argument.
Represents a discrete type definition, describing a native type class.
constexpr bool isValid() const
Gets if the type is considered a valid, registered type.
Provides a weakly referenced view over the contents of a string.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
@ TexturesFailed
One or more new textures have started fetching.
@ TexturesReady
All textures required have been fetched successfully, will be used next frame.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Handle to a Component instance.
ComponentType * resolveComponent() const
static const ResourceHandle_t NoHandle
Handle representing a default (or none if default not present) resource.
ComponentHandle createComponent() override
void destroyComponent(ComponentHandle handle) override