1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qquick3dsceneenvironment_p.h"
5#include "qquick3dobject_p.h"
6#include "qquick3dtexture_p.h"
7#include "qquick3dcubemaptexture_p.h"
8#include "qquick3ddebugsettings_p.h"
9
10QT_BEGIN_NAMESPACE
11
12/*!
13 \qmltype SceneEnvironment
14 \inherits Object3D
15 \inqmlmodule QtQuick3D
16 \brief Lets you configure how a scene is rendered.
17
18 SceneEnvironment defines a set of global properties for how a scene should be rendered.
19
20 \note The QtQuick3D.Helpers module offers an \l ExtendedSceneEnvironment
21 type which inherits from SceneEnvironment and adds a number of built-in
22 effects on top.
23
24 To use SceneEnvironment or \l ExtendedSceneEnvironment, associate the
25 \l{View3D::environment}{environment property} of a View3D with an instance
26 of these types. The object can be declared inline, for example like this:
27
28 \qml
29 View3D {
30 environment: SceneEnvironment {
31 antialiasingMode: SceneEnvironment.MSAA
32 tonemapMode: SceneEnvironment.TonemapModeFilmic
33 backgroundMode: SceneEnvironment.SkyBox
34 lightProbe: Texture {
35 source: "panoramic_hdri_background.hdr"
36 }
37 }
38 }
39 \endqml
40
41 Alternatively, the environment object can be defined separately. It can
42 then be referenced by one or more View3D objects. An example code snippet,
43 using \l ExtendedSceneEnvironment this time:
44
45 \qml
46 ExtendedSceneEnvironment {
47 id: myEnv
48 vignetteEnabled: true
49 }
50
51 View3D {
52 width: parent.width / 2
53 environment: myEnv
54 }
55
56 View3D {
57 width: parent.width / 2
58 x: parent.width / 2
59 environment: myEnv
60 }
61 \endqml
62
63 \section1 Feature Overview
64
65 \list
66
67 \li Anti-aliasing settings. See \l{Anti-Aliasing Best Practices} for an
68 overview of this topic. The relevant properties are \l antialiasingMode, \l
69 antialiasingQuality, \l specularAAEnabled, \l temporalAAEnabled, \l
70 temporalAAStrength. In addition, if \l ExtendedSceneEnvironment is used,
71 another method is available via
72 \l{ExtendedSceneEnvironment::fxaaEnabled}{fxaaEnabled}.
73
74 \li Screen space ambient occlusion. The relevant properties are
75 \l aoEnabled, \l aoStrength, \l aoBias, \l aoDistance, \l aoDither,
76 \l aoSampleRate, \l aoSoftness.
77
78 \li Clear color, skybox, image-based lighting. For more information on IBL,
79 see \l{Using Image-Based Lighting}. The relevant properties are \l
80 backgroundMode, \l clearColor, \l lightProbe, \l probeExposure, \l
81 probeHorizon, \l probeOrientation, \l skyboxBlurAmount, \l skyBoxCubeMap.
82
83 \li Tonemapping. \l tonemapMode configures the tonemapping method that is
84 used to convert the high dynamic range color values to the 0-1 range at the
85 end of the graphics pipeline. \l ExtendedSceneEnvironment offers a few
86 additional properties, such as
87 \l{ExtendedSceneEnvironment::whitePoint}{whitePoint} and
88 \l{ExtendedSceneEnvironment::sharpnessAmount}{sharpnessAmount} that can be
89 used to tune the tonemapping calculations.
90
91 \li Depth buffer settings. The relevant properties are \l
92 depthPrePassEnabled, \l depthTestEnabled.
93
94 \li Post-processing effects. In addition to the built-in post-processing
95 effects provided by \l ExtendedSceneEnvironment, applications can provide
96 their own custom effects via the \l Effect type. The \l effects property is
97 a list of \l Effect instances.
98
99 \li Debug visualization settings, such as wireframe mode or rendering only
100 certain color contributions for the materials. This is controlled by the \l
101 DebugSettings object referenced from the \l debugSettings property. Most of
102 these settings can also be controlled interactively when a \l DebugView
103 item is added to the scene.
104
105 \li Fog settings. To enable fog, set an appropriately configured
106 \l [QML] Fog object in the \l [QML] fog property.
107
108 \li Lightmap baking settings. When pre-baked lightmaps are used for some
109 models in the scene, the \l Lightmapper object set in the \l lightmapper
110 property defines the settings used during the baking process.
111
112 \li Scissor settings. To apply a scissor different than the viewport, set
113 the \l scissorRect property.
114
115 \endlist
116
117 \sa ExtendedSceneEnvironment
118*/
119
120QQuick3DSceneEnvironment::QQuick3DSceneEnvironment(QQuick3DObject *parent)
121 : QQuick3DObject(*(new QQuick3DObjectPrivate(QQuick3DObjectPrivate::Type::SceneEnvironment)), parent)
122{
123 m_debugSettings = new QQuick3DDebugSettings(this);
124 m_debugSettingsSignalConnection = QObject::connect(sender: m_debugSettings, signal: &QQuick3DDebugSettings::changed, context: this,
125 slot: [this] { update(); });
126 QObject::connect(sender: m_debugSettings, signal: &QObject::destroyed, context: this,
127 slot: [this](QObject *obj) {
128 if (m_debugSettings == obj) {
129 m_debugSettings = nullptr;
130 update();
131 }
132 });
133}
134
135QQuick3DSceneEnvironment::~QQuick3DSceneEnvironment()
136{
137}
138
139/*!
140 \qmlproperty enumeration QtQuick3D::SceneEnvironment::antialiasingMode
141 \since 5.15
142
143 This property controls the antialiasing mode that is applied when rendering
144 the scene.
145
146 Possible values are:
147 \value SceneEnvironment.NoAA No antialiasing is applied.
148 \value SceneEnvironment.SSAA Supersample antialiasing is applied.
149 \value SceneEnvironment.MSAA Multisample antialiasing is applied.
150 \value SceneEnvironment.ProgressiveAA Progressive antialiasing is applied.
151
152 The default value is \c SceneEnvironment.NoAA.
153
154 \b Supersampling
155
156 The scene is rendered in a higher resolution, and then scaled down to
157 actual resolution.
158
159 \b Pros: High quality. Antialiases all scene content and not just geometry
160 silhouettes.
161
162 \b Cons: Usually more expensive than MSAA. Increases video memory usage.
163 Supported with View3D items with all renderMode except Inline, but since
164 the technique implies rendering to a texture first, enabling SSAA with a
165 renderMode of Underlay or Overlay will result in using an intermediate
166 texture and render pass that would normally not be needed, meaning the
167 performance costs may be more noticeable. It is recommended to use SSAA
168 only when the renderMode is the default Offscreen.
169
170 \b Multisampling
171
172 The edges of geometry are super-sampled, resulting in smoother silhouettes.
173 This technique has no effect on the materials inside geometry, however.
174
175 \b Pros: Works with any View3D item regardless of the renderMode. Good
176 results on geometry silhouettes, where aliasing is often most noticeable;
177 works with fast animation without issues. Performance depends purely on the
178 system's (GPU) capabilities.
179
180 \b Cons: Does not help with texture or reflection issues. Increases video
181 memory usage. Can be expensive to use on less powerful graphics hardware.
182 Can be controlled on a per-window basis or for individual View3D items
183 depending on the renderMode. When using Underlay/Overlay with an effect
184 applied or Offscreen, MSAA can be controlled for each View3D item. On the
185 other hand, using Underlay/Overlay without any effect or Inline will make
186 MSAA controlled per-window.
187
188 \note For View3D items with a \l{QtQuick3D::View3D::renderMode}{renderMode}
189 other than Underlay/Overlay with effects or Offscreen, multisampling can only
190 be enabled via the \l{QSurfaceFormat::setSamples()}{QSurfaceFormat} of the
191 QQuickWindow or QQuickView. This will then affect all content,
192 both 2D and 3D, in that window.
193
194 \b {Progressive antialiasing}
195
196 This property enables and sets the level of progressive antialiasing
197 applied to the scene.
198
199 When all content of the scene has stopped moving, the camera is jiggled
200 very slightly between frames, and the result of each new frame is blended
201 with the previous frames. The more frames you accumulate, the better
202 looking the result.
203
204 \b Pros: Provides great results when all content in the scene is standing still.
205
206 \b Cons: Does not take effect if any visual changes are occurring.
207 Expensive due to having to accumulate and blend. Increases video memory
208 usage.
209
210 \note Progressing antialiasing is not currently supported with multiview
211 rendering, and should not be used in VR/AR applications.
212
213 See \l{Anti-Aliasing Best Practices} for further discussion on
214 anti-aliasing methods.
215*/
216QQuick3DSceneEnvironment::QQuick3DEnvironmentAAModeValues QQuick3DSceneEnvironment::antialiasingMode() const
217{
218 return m_antialiasingMode;
219}
220
221/*!
222 \qmlproperty enumeration QtQuick3D::SceneEnvironment::antialiasingQuality
223 \since 5.15
224
225 This property sets the level of antialiasing applied to the scene.
226 Behavior depends on used antialiasingMode. With antialiasingMode
227 property set to \c NoAA this property doesn't have an effect.
228
229 Possible values are:
230 \value SceneEnvironment.Medium
231 SSAA: Antialiasing uses 1.2x supersampling resolution.\br
232 MSAA: Antialiasing uses 2 samples per pixel.\br
233 ProgressiveAA: Antialiasing uses 2 frames for final image.
234 \value SceneEnvironment.High
235 SSAA: Antialiasing uses 1.5x supersampling resolution.\br
236 MSAA: Antialiasing uses 4 samples per pixel.\br
237 ProgressiveAA: Antialiasing uses 4 frames for final image.
238 \value SceneEnvironment.VeryHigh
239 SSAA: Antialiasing uses 2.0x supersampling resolution.\br
240 MSAA: Antialiasing uses 8 samples per pixel.\br
241 ProgressiveAA: Antialiasing uses 8 frames for final image.
242
243 The default value is \c SceneEnvironment.High
244*/
245
246QQuick3DSceneEnvironment::QQuick3DEnvironmentAAQualityValues QQuick3DSceneEnvironment::antialiasingQuality() const
247{
248 return m_antialiasingQuality;
249}
250
251/*!
252 \qmlproperty enumeration QtQuick3D::SceneEnvironment::backgroundMode
253
254 This property controls if and how the background of the scene should be
255 cleared.
256
257 \note The clearing of the color buffer backing the View 3D does not always
258 happen: depending on the \l{QtQuick3D::View3D::renderMode}{renderMode}
259 property the View3D may not perform any clearing on its own, in which case
260 \c{SceneEnvironment.Transparent} and \c{SceneEnvironment.Color} have no
261 effect. Only the default \c Offscreen \l{View3D::renderMode}{render mode}
262 (rendering into a texture) supports all clearing modes. With the \c
263 Underlay mode, use \l{QQuickWindow::setColor()} or
264 \l[QtQuick]{Window::color}{Window.color} to control the clear color for the
265 Qt Quick scene. SkyBox is handled differently, as it implies drawing actual
266 geometry, so that works identically across all render modes.
267
268 \value SceneEnvironment.Transparent
269 The scene is cleared to be transparent. This is useful to render 3D content on top of another item.
270 This mode has no effect when the View3D is using a renderMode of Underlay or Overlay without any
271 post processing enabled.
272 \value SceneEnvironment.Color
273 The scene is cleared with the color specified by the clearColor property.
274 This mode has no effect when the View3D is using a renderMode of Underlay or Overlay without any
275 post processing enabled.
276 \value SceneEnvironment.SkyBox
277 The scene will not be cleared, but instead a SkyBox or Skydome will be rendered. The SkyBox
278 is defined using the HDRI map defined in the lightProbe property.
279 \value SceneEnvironment.SkyBoxCubeMap
280 The scene will not be cleared, but instead a SkyBox or Skydome will be rendered. The SkyBox
281 is defined using the cubemap defined in the skyBoxCubeMap property.
282
283 The default value is \c SceneEnvironment.Transparent
284
285 Take the following example. The Suzanne model is expected to be
286 pre-processed with the \c balsam tool and is sourced from the
287 \l{https://github.com/KhronosGroup/glTF-Sample-Models}{glTF Sample Models}
288 repository.
289
290 \qml
291 import QtQuick
292 import QtQuick3D
293 import QtQuick3D.Helpers
294
295 Item {
296 width: 1280
297 height: 720
298
299 View3D {
300 id: v3d
301 anchors.fill: parent
302
303 environment: ExtendedSceneEnvironment {
304 backgroundMode: SceneEnvironment.SkyBox
305 lightProbe: Texture { source: "00455_OpenfootageNET_field_low.hdr" }
306
307 glowEnabled: true
308 glowStrength: 1.25
309 glowBloom: 0.25
310 glowBlendMode: ExtendedSceneEnvironment.GlowBlendMode.Additive
311 }
312
313 DirectionalLight {
314 }
315
316 Suzanne {
317 scale: Qt.vector3d(50, 50, 50)
318 z: -500
319 }
320
321 PerspectiveCamera {
322 id: camera
323 }
324
325 WasdController {
326 controlledObject: camera
327 }
328 }
329 }
330 \endqml
331
332 Using image-based lighting in additional to the DirectionalLight and also
333 using the light probe texture as the skybox gives us the following:
334
335 \image sceneenvironment_background_ibl.jpg
336
337 What happens if there is no light probe?
338
339 \qml
340 backgroundMode: SceneEnvironment.Transparent
341 \endqml
342
343 Here the background is provided not by the View3D but by the QQuickWindow
344 or QQuickView hosting the 2D and 3D scene. Lighting is based on the
345 DirectionalLight only.
346
347 \image sceneenvironment_background_transparent.jpg
348
349 Using a fixed clear color:
350
351 \qml
352 backgroundMode: SceneEnvironment.Color
353 clearColor: "green"
354 \endqml
355
356 \image sceneenvironment_background_color.jpg
357
358 \sa lightProbe, QQuickWindow::setColor(), Window::color, View3D
359*/
360
361QQuick3DSceneEnvironment::QQuick3DEnvironmentBackgroundTypes QQuick3DSceneEnvironment::backgroundMode() const
362{
363 return m_backgroundMode;
364}
365
366/*!
367 \qmlproperty color QtQuick3D::SceneEnvironment::clearColor
368
369 This property defines which color will be used to clear the viewport when
370 using \c SceneEnvironment.Color for the backgroundMode property.
371
372 The default value is \c Qt::black
373
374 \sa backgroundMode
375*/
376
377QColor QQuick3DSceneEnvironment::clearColor() const
378{
379 return m_clearColor;
380}
381
382/*!
383 \qmlproperty float QtQuick3D::SceneEnvironment::aoStrength
384
385 This property defines the amount of ambient occulusion applied. Ambient
386 occulusion is a form of approximated global illumination which causes
387 non-directional self-shadowing where objects are close together.
388 A value of 100 causes full darkness shadows; lower values cause the
389 shadowing to appear lighter. A value of 0 disables ambient occlusion
390 entirely, improving performance at a cost to the visual realism of 3D
391 objects rendered in the scene.
392
393 All values other than 0 have the same impact to the performance.
394
395 The default value is 0.0. The maximum value is 100.0.
396
397 A value of 0 is equivalent to setting \l aoEnabled to false.
398
399 Pictured here with the default aoSoftness and aoDistance:
400
401 \table
402 \header
403 \li aoStrength of 0 (AO disabled)
404 \li aoStrength of 100
405 \li aoStrength of 50
406 \row
407 \li \image sceneenvironment_ao_off.jpg
408 \li \image sceneenvironment_ao_full_strength.jpg
409 \li \image sceneenvironment_ao_half_strength.jpg
410 \endtable
411
412 \note Getting visually good-looking screen space ambient occlusion is
413 dependent on carefully tuning a number of related parameters, such as \l
414 aoStrength, \l aoSoftness, \l aoDistance, \l aoDither, \l aoBias, and \l
415 aoSampleRate.
416
417 \sa aoEnabled, aoDistance, aoSoftness
418*/
419float QQuick3DSceneEnvironment::aoStrength() const
420{
421 return m_aoStrength;
422}
423
424/*!
425 \qmlproperty float QtQuick3D::SceneEnvironment::aoDistance
426
427 This property defines roughly how far ambient occlusion shadows spread away
428 from objects. Greater distances cause increasing impact to performance.
429
430 The default value is 5.0.
431
432 Pictured here with the default aoSoftness and the maximum aoStrength:
433
434 \table
435 \header
436 \li aoDistance of 5
437 \li aoDistance of 1
438 \row
439 \li \image sceneenvironment_ao_distance_5.jpg
440 \li \image sceneenvironment_ao_distance_1.jpg
441 \endtable
442
443 \note Getting visually good-looking screen space ambient occlusion is
444 dependent on carefully tuning a number of related parameters, such as \l
445 aoStrength, \l aoSoftness, \l aoDistance, \l aoDither, \l aoBias, and \l
446 aoSampleRate.
447
448 \sa aoStrength, aoSoftness
449*/
450float QQuick3DSceneEnvironment::aoDistance() const
451{
452 return m_aoDistance;
453}
454
455/*!
456 \qmlproperty float QtQuick3D::SceneEnvironment::aoSoftness
457
458 This property defines how smooth the edges of the ambient occlusion shading
459 are.
460
461 The value must be between 0.0 and 50.0. The default value is 50.0.
462
463 Pictured here with the default aoDistance and the maximum aoStrength:
464
465 \table
466 \header
467 \li aoSoftness of 50
468 \li aoSoftness of 25
469 \row
470 \li \image sceneenvironment_ao_softness_default.jpg
471 \li \image sceneenvironment_ao_softness_half.jpg
472 \endtable
473
474 \note Getting visually good-looking screen space ambient occlusion is
475 dependent on carefully tuning a number of related parameters, such as \l
476 aoStrength, \l aoSoftness, \l aoDistance, \l aoDither, \l aoBias, and \l
477 aoSampleRate.
478
479 \sa aoStrength, aoDistance
480*/
481float QQuick3DSceneEnvironment::aoSoftness() const
482{
483 return m_aoSoftness;
484}
485
486/*!
487 \qmlproperty bool QtQuick3D::SceneEnvironment::aoDither
488
489 When this property is enabled it scatters the edges of the ambient
490 occlusion shadow bands to improve smoothness (at the risk of sometimes
491 producing obvious patterned artifacts).
492
493 \note Very large distances between the clipping planes of your camera may
494 cause problems with ambient occlusion. If you are seeing odd banding in
495 your ambient occlusion, try adjusting the \l {PerspectiveCamera::}{clipFar}
496 property of your camera to be closer to your content.
497
498 The default value is \c false.
499
500 \sa {QtQuick3D::PerspectiveCamera::clipFar}{PerspectiveCamera.clipFar},
501 {QtQuick3D::OrthographicCamera::clipFar}{OrthographicCamera.clipFar}
502*/
503bool QQuick3DSceneEnvironment::aoDither() const
504{
505 return m_aoDither;
506}
507
508/*!
509 \qmlproperty int QtQuick3D::SceneEnvironment::aoSampleRate
510
511 This property defines ambient occlusion quality (more shades of gray) at
512 the expense of performance.
513
514 The value must be 2, 3, or 4. The default value is 2.
515*/
516int QQuick3DSceneEnvironment::aoSampleRate() const
517{
518 return m_aoSampleRate;
519}
520
521/*!
522 \qmlproperty float QtQuick3D::SceneEnvironment::aoBias
523
524 This property defines a cutoff distance preventing objects from exhibiting
525 ambient occlusion at close distances. Higher values increase the distance
526 required between objects before ambient occlusion is seen.
527
528 \note If you see ambient occlusion shadowing on objects where there should
529 be no shadowing, increase the value slightly to clip away close results.
530
531 The default value is 0.0.
532*/
533float QQuick3DSceneEnvironment::aoBias() const
534{
535 return m_aoBias;
536}
537
538/*!
539 \qmlproperty QtQuick3D::Texture QtQuick3D::SceneEnvironment::lightProbe
540
541 This property defines an image used to light the scene, either instead of,
542 or in addition to standard lights.
543
544 The image is preferably a high-dynamic range image or a \l{Pre-generating
545 IBL cubemap}{pre-generated cubemap}. Pre-baking provides significant
546 performance improvements at run time, because no time is spent on filtering
547 and mipmap generation. If the source is a .hdr or other image, the GPU-based
548 pre-processing happens at run time after loading the image file, and that
549 can be potentially time consuming, in particular on embedded and mobile
550 hardware. Therefore, it is strongly recommended that applications
551 pre-process .hdr images at latest at build time, as described
552 \l{Pre-generating IBL cubemap}{here}.
553
554 \note Using a Texture with \l{Texture::sourceItem}{sourceItem} is not
555 supported in combination with this property. Pre-filtering of all mip
556 levels for dynamic Qt Quick content is typically not reasonable in practice
557 due to performance implications.
558
559 For more information on image-based lighting, see \l{Using Image-Based Lighting}.
560
561 \note The light probe texture, when the property is set to a valid Texture,
562 is used for lighting regardless of the \l backgroundMode. However, when \l
563 backgroundMode is set to \c{SceneEnvironment.SkyBox}, the texture is also
564 used to render the scene background as a skybox.
565
566 The examples below were generated with varying the \l backgroundMode in the
567 environment of the following scene. The scene has no DirectionLight,
568 PointLight, or SpotLight. All lighting is based on the panoramic HDRI
569 image.
570
571 \qml
572 import QtQuick
573 import QtQuick3D
574 import QtQuick3D.Helpers
575
576 Item {
577 width: 1280
578 height: 720
579
580 View3D {
581 id: v3d
582 anchors.fill: parent
583
584 environment: ExtendedSceneEnvironment {
585 backgroundMode: SceneEnvironment.SkyBox
586 lightProbe: Texture { source: "00455_OpenfootageNET_field_low.hdr" }
587
588 tonemapMode: SceneEnvironment.TonemapModeFilmic
589 sharpnessAmount: 0.4
590
591 glowEnabled: true
592 glowStrength: 1.25
593 glowBloom: 0.25
594 glowBlendMode: ExtendedSceneEnvironment.GlowBlendMode.Additive
595 }
596
597 Node {
598 scale: Qt.vector3d(100, 100, 100)
599
600 Sponza {
601 }
602
603 Suzanne {
604 y: 1
605 scale: Qt.vector3d(0.5, 0.5, 0.5)
606 eulerRotation.y: -90
607 }
608 }
609
610 PerspectiveCamera {
611 id: camera
612 y: 100
613 }
614
615 WasdController {
616 controlledObject: camera
617 }
618 }
619 }
620 \endqml
621
622 Results with the above environment:
623
624 \image sceneenvironment_lightprobe.jpg
625 \image sceneenvironment_lightprobe_2.jpg
626
627 Switching the backgroundMode to \c{SceneEnvironment.Transparent} would give us:
628
629 \image sceneenvironment_lightprobe_transparent.jpg
630 \image sceneenvironment_lightprobe_transparent_2.jpg
631
632 Here the lighting of the 3D scene is the same as before, meaning the
633 materials use the light probe in the lighting calculations the same way as
634 before, but there is no skybox rendered. The background is white since that
635 is the default clear color of the QQuickWindow hosting the 2D and 3D scene.
636
637 It is valid to set the lightProbe property value back to the default null.
638 This unassigns the previously associated texture. For example, let's use
639 the Delete key to dynamically toggle between image-based lighting with a
640 skybox, and no image-based lighting with a fixed clear color for the
641 background:
642
643 \qml
644 environment: ExtendedSceneEnvironment {
645 id: env
646
647 backgroundMode: SceneEnvironment.SkyBox
648 lightProbe: iblTex
649
650 tonemapMode: SceneEnvironment.TonemapModeFilmic
651 sharpnessAmount: 0.4
652
653 glowEnabled: true
654 glowStrength: 1.25
655 glowBloom: 0.25
656 glowBlendMode: ExtendedSceneEnvironment.GlowBlendMode.Additive
657 }
658
659 Texture {
660 id: iblTex
661 source: "00455_OpenfootageNET_field_low.hdr"
662 }
663
664 focus: true
665 Keys.onDeletePressed: {
666 if (env.backgroundMode == SceneEnvironment.SkyBox) {
667 env.backgroundMode = SceneEnvironment.Color;
668 env.clearColor = "green";
669 env.lightProbe = null;
670 } else {
671 env.backgroundMode = SceneEnvironment.SkyBox;
672 env.lightProbe = iblTex;
673 }
674 }
675 \endqml
676
677 Pressing Delete gives the following result. Remember that the scene used
678 here has no lights so all 3D models appear completely black.
679
680 \image sceneenvironment_lightprobe_null.jpg
681 \image sceneenvironment_lightprobe_null_2.jpg
682
683 While lightProbe is commonly used in combination with Texture instances
684 that source their data from an image file (typically .hdr or .ktx), it can
685 also makes sense to associate with a Texture that uses in-memory,
686 \l{Texture::textureData}{procedurally generated image data}. A prime
687 example of this is a Texture where the image data is generated by \l
688 ProceduralSkyTextureData from the QtQuick3D.Helpers module:
689
690 \qml
691 backgroundMode: SceneEnvironment.SkyBox
692 lightProbe: Texture {
693 textureData: ProceduralSkyTextureData {
694 }
695 }
696 \endqml
697
698 This gives us a procedurally generated HDR skybox texture that is now used
699 both as the skybox and for image-based lighting:
700
701 \image sceneenvironment_lightprobe_proceduralsky.jpg
702
703 \sa backgroundMode, {Using Image-Based Lighting}, {Pre-generating IBL
704 cubemap}, probeExposure, probeHorizon, probeOrientation, ProceduralSkyTextureData
705*/
706QQuick3DTexture *QQuick3DSceneEnvironment::lightProbe() const
707{
708 return m_lightProbe;
709}
710
711/*!
712 \qmlproperty float QtQuick3D::SceneEnvironment::probeExposure
713
714 This property modifies the amount of light emitted by the light probe. Part
715 of the tonemapping is exposure mapping, and this property adjusts how
716 the light values in the light probes get tonemaped.
717
718 By default exposure is set to is 1.0
719
720 \note This property does not have an effect when \l tonemapMode is set to
721 \c SceneEnvironment.TonemapModeNone.
722
723 \sa lightProbe, probeHorizon, probeOrientation
724*/
725float QQuick3DSceneEnvironment::probeExposure() const
726{
727 return m_probeExposure;
728}
729
730/*!
731 \qmlproperty float QtQuick3D::SceneEnvironment::probeHorizon
732
733 This property when defined with increasing values adds darkness (black)
734 to the bottom half of the environment, forcing the lighting to come
735 predominantly from the top of the image (and removing specific reflections
736 from the lower half). This property is useful for accounting for a ground
737 plane that would have the effect of obscuring the reflection of the light
738 probe from the ground. This is necessary because light probe contributions
739 come directily from the image without consideration for the content of the
740 scene.
741
742 The expected value range for the probeHorizon property is between 0.0
743 and 1.0. Any value outside of this range will be clamped to the
744 expected range.
745
746 By default probeHorizon is set to 0.0 which means the whole light probe
747 is used without adjustment.
748
749 \note The probeHorizon property only affects materials lighting, and has
750 no effect on the rendering of the sky box.
751
752 \sa lightProbe, probeExposure, probeOrientation
753*/
754float QQuick3DSceneEnvironment::probeHorizon() const
755{
756 return m_probeHorizon;
757}
758
759/*!
760 \qmlproperty vector3d QtQuick3D::SceneEnvironment::probeOrientation
761
762 This property when defines the orientation of the light probe. Orientation
763 is defined in terms of euler angles in degrees over the x, y, and z axes.
764
765 \note This value augments how the lightProbe Texture is sampled in combination
766 with any texture rotations and offsets set on the lightProbe texture.
767
768 \sa lightProbe, probeHorizon, probeExposure
769*/
770QVector3D QQuick3DSceneEnvironment::probeOrientation() const
771{
772 return m_probeOrientation;
773}
774
775/*!
776 \qmlproperty bool QtQuick3D::SceneEnvironment::temporalAAEnabled
777
778 When this property is enabled temporal antialiasing will be used.
779
780 The camera is jiggled very slightly between frames, and the result of each
781 new frame is blended with the previous frame.
782
783 \note Temporal antialiasing doesn't have an effect when antialiasingMode is MSAA.
784 \note When combined with ProgressiveAA antialiasingMode, temporalAA is used
785 when scene animates while ProgressiveAA is used once animations stop.
786
787 \b Pros: Due to the jiggling camera it finds real details that were otherwise
788 lost; low impact on performance.
789
790 \b Cons: Fast-moving objects cause one-frame ghosting.
791
792 \default false
793
794 \note Temporal antialiasing is not currently supported with multiview
795 rendering, and should not be used in VR/AR applications.
796*/
797bool QQuick3DSceneEnvironment::temporalAAEnabled() const
798{
799 return m_temporalAAEnabled;
800}
801
802/*!
803 \qmlproperty float QtQuick3D::SceneEnvironment::temporalAAStrength
804 \since 5.15
805
806 This property modifies the amount of temporal movement (antialiasing).
807 This has an effect only when temporalAAEnabled property is true.
808
809 \default 0.3
810
811 \sa temporalAAEnabled
812*/
813float QQuick3DSceneEnvironment::temporalAAStrength() const
814{
815 return m_temporalAAStrength;
816}
817
818/*!
819 \qmlproperty bool QtQuick3D::SceneEnvironment::specularAAEnabled
820 \since 6.4
821
822 When this property is enabled, specular aliasing will be mitigated.
823 Specular aliasing is often visible in form of bright dots, possibly
824 flickering when moving the camera around.
825
826 The default value is false.
827
828 \table
829 \header
830 \li Specular AA disabled
831 \li Specular AA enabled
832 \row
833 \li \image specular_aa_off.jpg
834 \li \image specular_aa_on.jpg
835 \endtable
836*/
837bool QQuick3DSceneEnvironment::specularAAEnabled() const
838{
839 return m_specularAAEnabled;
840}
841
842/*!
843 \qmlproperty bool QtQuick3D::SceneEnvironment::depthTestEnabled
844
845 The default value is \c true. By default the renderer classifies the objects
846 in the scene either as \c opaque or as \c semi-transparent. The objects
847 (sub-meshes with the associated material) in the \c opaque list are rendered
848 first, with depth testing and depth write enabled, providing optimal
849 Z-culling for typical 3D objects that have no semi-transparent regions. The
850 objects in the \c semi-transparent list are rendered with depth write
851 disabled, although still with depth testing enabled (to test against the
852 opaque objects), in back to front order (sorted based on their center point's
853 distance from the camera). This allows correct blending ("see through") for
854 3D objects that involve semi-transparent regions on their surface, either
855 due to the \l{Node::opacity}{node opacity} or due to some color or texture
856 map in the material.
857
858 When this property is set to \c {false}, the Z-buffer is not written and
859 tested against, the depth test is skipped, and all objects, including fully
860 opaque ones, are rendered in one go, sorted back to front.
861
862 Setting this property to \c false should be rarely needed. It can be useful
863 in scenes where it is known that there is little benefit in the two-round
864 approach because either there are very few opaque objects, or they are
865 transformed in a way that a single back to front sorted pass performs
866 better.
867
868 \note Setting this property to \c false may cause rendering errors in
869 certain scenes. In addition, some features, such as shadows, ambient
870 occlusion, \c SCREEN_TEXTURE and \c DEPTH_TEXTURE in custom materials and
871 effects, will not behave correctly without enabling depth buffer usage.
872
873 \note This flag has no control over the presence of a depth or
874 depth-stencil buffer. Such buffers may still be allocated even when this is
875 set to \c false.
876*/
877bool QQuick3DSceneEnvironment::depthTestEnabled() const
878{
879 return m_depthTestEnabled;
880}
881/*!
882 \qmlproperty bool QtQuick3D::SceneEnvironment::depthPrePassEnabled
883
884 When enabled, the renderer performs a Z-prepass for opaque objects, meaning
885 it renders them with a simple shader and color write disabled in order to
886 get the depth buffer pre-filled before issuing draw calls for the main
887 rendering passes.
888
889 This can improve performance depending on the scene contents. It is
890 typically scenes with lots of overlapping objects and expensive fragment
891 shading that benefit from this. At the same time, it is worth noting that
892 the renderer performs front to back sorting for opaque objects, which in
893 itself helps reducing unnecessary fragment shading, and therefore the
894 Z-prepass does not always bring significant improvements.
895
896 On GPUs that use a tiled rendering architecture, which is common in mobile
897 and embedded systems, it is recommended to set this to \c false.
898
899 The default value is \c false.
900
901 \note This property has no effect when depth testing is disabled.
902*/
903bool QQuick3DSceneEnvironment::depthPrePassEnabled() const
904{
905 return m_depthPrePassEnabled;
906}
907
908/*!
909 \qmlproperty List<QtQuick3D::Effect> QtQuick3D::SceneEnvironment::effects
910 \since 5.15
911
912 This property contains a list of post-processing effects that will be
913 applied to the entire viewport. The result of each effect is fed to the
914 next so the order is significant.
915
916 \note For technical reasons, adding the same \l{QtQuick3D::Effect}{Effect}
917 node several times to the list is unsupported and will give unexpected results.
918*/
919QQmlListProperty<QQuick3DEffect> QQuick3DSceneEnvironment::effects()
920{
921 return QQmlListProperty<QQuick3DEffect>(this,
922 nullptr,
923 QQuick3DSceneEnvironment::qmlAppendEffect,
924 QQuick3DSceneEnvironment::qmlEffectsCount,
925 QQuick3DSceneEnvironment::qmlEffectAt,
926 QQuick3DSceneEnvironment::qmlClearEffects);
927}
928
929/*!
930 \qmlproperty enumeration QtQuick3D::SceneEnvironment::tonemapMode
931 \since 6.0
932
933 This property defines how colors are tonemapped before rendering. All
934 rendering in Qt Quick 3D is performed in linear color space and can in
935 many cases lead to generating color values that are not displayable. The
936 tonemapMode determines the technique that is used to remap colors into a
937 displayable range.
938
939 The default value is \c SceneEnvironment.TonemapModeLinear
940
941 \value SceneEnvironment.TonemapModeNone
942 All Tonemapping is bypassed. This mode is useful when performing post
943 processing effects.
944 \value SceneEnvironment.TonemapModeLinear
945 Linear tonemapping is applied. Colors are gamma corrected and returned
946 in sRGB color space.
947 \value SceneEnvironment.TonemapModeAces
948 Academy Color Encoding System tonemapping is applied.
949 \value SceneEnvironment.TonemapModeHejlDawson
950 Hejl-Dawson tonemapping is applied.
951 \value SceneEnvironment.TonemapModeFilmic
952 Filmic tonemapping is applied.
953
954 See \l{ExtendedSceneEnvironment::tonemapMode}{ExtendedSceneEnvironment} for
955 an example of these different modes.
956
957 \note When using post-processing effects, most effects expect untonemapped
958 linear color data. With application-provided, custom effects implemented
959 via the \l Effect type, it is important to know that starting with Qt 6.5
960 effects can safely assume that they work with linear color data, and
961 tonemapping is performed automatically on the output of the last effect in
962 the chain. If there is a need to customize tonemapping completely, consider
963 setting the \c SceneEnvironment.TonemapModeNone value to disable the
964 built-in tonemapper, and perform the appropriate adjustments on the color
965 value in the last effect in the chain instead. This does not apply to the
966 built-in effects of \l ExtendedSceneEnvironment, because those
967 automatically take care of proper tonemapping regardless of what
968 combination of built-in effects are enabled in the environment.
969*/
970QQuick3DSceneEnvironment::QQuick3DEnvironmentTonemapModes QQuick3DSceneEnvironment::tonemapMode() const
971{
972 return m_tonemapMode;
973}
974
975/*!
976 \qmlproperty float QtQuick3D::SceneEnvironment::skyboxBlurAmount
977 \since 6.4
978
979 This property determines how much much the skybox should be blurred when
980 using \c SceneEnvironment.SkyBox for the \l backgroundMode property. The
981 default value is \c 0.0 which means there is no blurring.
982
983 Acceptable values range between 0.0 and 1.0, all other values will be clamped
984 to this range.
985
986*/
987
988float QQuick3DSceneEnvironment::skyboxBlurAmount() const
989{
990 return m_skyboxBlurAmount;
991}
992
993/*!
994 \qmlproperty QtQuick3D::DebugSettings QtQuick3D::SceneEnvironment::debugSettings
995 \since 6.5
996
997 This property specifies a \c DebugSettings object which is used to
998 configure the debugging tools of the renderer. During construction
999 the SceneEnvironment automatically creates a DebugSettings object
1000 associated with itself, and therefore setting a custom DebugSettings
1001 is usually not required.
1002
1003 An example of rendering the scene with wireframe mode enabled:
1004 \image debugsettings_wireframe.jpg
1005
1006 Visualizing the normal vectors of the meshes:
1007 \image debugsettings_normals.jpg
1008
1009 Visualizing the specular lighting contribution:
1010 \image debugsettings_specular.jpg
1011
1012 \sa DebugSettings
1013*/
1014
1015QQuick3DDebugSettings *QQuick3DSceneEnvironment::debugSettings() const
1016{
1017 return m_debugSettings;
1018}
1019
1020/*!
1021 \qmlproperty rect QtQuick3D::SceneEnvironment::scissorRect
1022 \since 6.5
1023
1024 This property defines a scissor rectangle in view coordinates, with the
1025 top-left corner at [0, 0]
1026*/
1027
1028QRect QQuick3DSceneEnvironment::scissorRect() const
1029{
1030 return m_scissorRect;
1031}
1032
1033void QQuick3DSceneEnvironment::setAntialiasingMode(QQuick3DSceneEnvironment::QQuick3DEnvironmentAAModeValues antialiasingMode)
1034{
1035 if (m_antialiasingMode == antialiasingMode)
1036 return;
1037
1038 m_antialiasingMode = antialiasingMode;
1039 emit antialiasingModeChanged();
1040 update();
1041}
1042
1043void QQuick3DSceneEnvironment::setAntialiasingQuality(QQuick3DSceneEnvironment::QQuick3DEnvironmentAAQualityValues antialiasingQuality)
1044{
1045 if (m_antialiasingQuality == antialiasingQuality)
1046 return;
1047
1048 m_antialiasingQuality = antialiasingQuality;
1049 emit antialiasingQualityChanged();
1050 update();
1051}
1052
1053void QQuick3DSceneEnvironment::setBackgroundMode(QQuick3DSceneEnvironment::QQuick3DEnvironmentBackgroundTypes backgroundMode)
1054{
1055 if (m_backgroundMode == backgroundMode)
1056 return;
1057
1058 m_backgroundMode = backgroundMode;
1059 emit backgroundModeChanged();
1060 update();
1061}
1062
1063void QQuick3DSceneEnvironment::setClearColor(const QColor &clearColor)
1064{
1065 if (m_clearColor == clearColor)
1066 return;
1067
1068 m_clearColor = clearColor;
1069 emit clearColorChanged();
1070 update();
1071}
1072
1073void QQuick3DSceneEnvironment::setAoStrength(float aoStrength)
1074{
1075 if (qFuzzyCompare(p1: m_aoStrength, p2: aoStrength))
1076 return;
1077
1078 m_aoStrength = aoStrength;
1079
1080 const bool aoEnabled = !(qFuzzyIsNull(f: m_aoStrength) || qFuzzyIsNull(f: m_aoDistance));
1081 setAoEnabled(aoEnabled);
1082
1083 emit aoStrengthChanged();
1084 update();
1085}
1086
1087void QQuick3DSceneEnvironment::setAoDistance(float aoDistance)
1088{
1089 if (qFuzzyCompare(p1: m_aoDistance, p2: aoDistance))
1090 return;
1091
1092 m_aoDistance = aoDistance;
1093
1094 const bool aoEnabled = !(qFuzzyIsNull(f: m_aoStrength) || qFuzzyIsNull(f: m_aoDistance));
1095 setAoEnabled(aoEnabled);
1096
1097 emit aoDistanceChanged();
1098 update();
1099}
1100
1101void QQuick3DSceneEnvironment::setAoSoftness(float aoSoftness)
1102{
1103 if (qFuzzyCompare(p1: m_aoSoftness, p2: aoSoftness))
1104 return;
1105
1106 m_aoSoftness = aoSoftness;
1107 emit aoSoftnessChanged();
1108 update();
1109}
1110
1111void QQuick3DSceneEnvironment::setAoDither(bool aoDither)
1112{
1113 if (m_aoDither == aoDither)
1114 return;
1115
1116 m_aoDither = aoDither;
1117 emit aoDitherChanged();
1118 update();
1119}
1120
1121void QQuick3DSceneEnvironment::setAoSampleRate(int aoSampleRate)
1122{
1123 if (m_aoSampleRate == aoSampleRate)
1124 return;
1125
1126 m_aoSampleRate = aoSampleRate;
1127 emit aoSampleRateChanged();
1128 update();
1129}
1130
1131void QQuick3DSceneEnvironment::setAoBias(float aoBias)
1132{
1133 if (qFuzzyCompare(p1: m_aoBias, p2: aoBias))
1134 return;
1135
1136 m_aoBias = aoBias;
1137 emit aoBiasChanged();
1138 update();
1139}
1140
1141void QQuick3DSceneEnvironment::setLightProbe(QQuick3DTexture *lightProbe)
1142{
1143 if (m_lightProbe == lightProbe)
1144 return;
1145
1146 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSceneEnvironment::setLightProbe, newO: lightProbe, oldO: m_lightProbe);
1147
1148 m_lightProbe = lightProbe;
1149 emit lightProbeChanged();
1150 update();
1151}
1152
1153void QQuick3DSceneEnvironment::setProbeExposure(float probeExposure)
1154{
1155 if (qFuzzyCompare(p1: m_probeExposure, p2: probeExposure))
1156 return;
1157
1158 m_probeExposure = probeExposure;
1159 emit probeExposureChanged();
1160 update();
1161}
1162
1163void QQuick3DSceneEnvironment::setProbeHorizon(float probeHorizon)
1164{
1165 // clamp value to expected range
1166 probeHorizon = qBound(min: 0.0f, val: probeHorizon, max: 1.0f);
1167
1168 if (qFuzzyCompare(p1: m_probeHorizon, p2: probeHorizon))
1169 return;
1170
1171 m_probeHorizon = probeHorizon;
1172 emit probeHorizonChanged();
1173 update();
1174}
1175
1176void QQuick3DSceneEnvironment::setProbeOrientation(const QVector3D &orientation)
1177{
1178 if (qFuzzyCompare(v1: m_probeOrientation, v2: orientation))
1179 return;
1180
1181 m_probeOrientation = orientation;
1182 emit probeOrientationChanged();
1183 update();
1184}
1185
1186void QQuick3DSceneEnvironment::setDepthTestEnabled(bool depthTestEnabled)
1187{
1188 if (m_depthTestEnabled == depthTestEnabled)
1189 return;
1190
1191 m_depthTestEnabled = depthTestEnabled;
1192 emit depthTestEnabledChanged();
1193 update();
1194}
1195
1196void QQuick3DSceneEnvironment::setDepthPrePassEnabled(bool depthPrePassEnabled)
1197{
1198 if (m_depthPrePassEnabled == depthPrePassEnabled)
1199 return;
1200
1201 m_depthPrePassEnabled = depthPrePassEnabled;
1202 emit depthPrePassEnabledChanged();
1203 update();
1204}
1205
1206void QQuick3DSceneEnvironment::setTonemapMode(QQuick3DSceneEnvironment::QQuick3DEnvironmentTonemapModes tonemapMode)
1207{
1208 if (m_tonemapMode == tonemapMode)
1209 return;
1210
1211 m_tonemapMode = tonemapMode;
1212 emit tonemapModeChanged();
1213 update();
1214}
1215
1216bool QQuick3DSceneEnvironment::useBuiltinTonemapper() const
1217{
1218 return true;
1219}
1220
1221QSSGRenderGraphObject *QQuick3DSceneEnvironment::updateSpatialNode(QSSGRenderGraphObject *node)
1222{
1223 // Don't do anything, these properties get set by the scene renderer
1224 return node;
1225}
1226
1227void QQuick3DSceneEnvironment::itemChange(QQuick3DObject::ItemChange change, const QQuick3DObject::ItemChangeData &value)
1228{
1229 if (change == QQuick3DObject::ItemSceneChange)
1230 updateSceneManager(manager: value.sceneManager);
1231}
1232
1233const QVector<QQuick3DEffect *> &QQuick3DSceneEnvironment::effectList() const
1234{
1235 return m_effects;
1236}
1237
1238void QQuick3DSceneEnvironment::updateSceneManager(QQuick3DSceneManager *manager)
1239{
1240 if (manager) {
1241 QQuick3DObjectPrivate::refSceneManager(obj: m_lightProbe, mgr&: *manager);
1242 QQuick3DObjectPrivate::refSceneManager(obj: m_skyBoxCubeMap, mgr&: *manager);
1243 } else {
1244 QQuick3DObjectPrivate::derefSceneManager(obj: m_lightProbe);
1245 QQuick3DObjectPrivate::derefSceneManager(obj: m_skyBoxCubeMap);
1246 }
1247}
1248
1249void QQuick3DSceneEnvironment::setTemporalAAEnabled(bool temporalAAEnabled)
1250{
1251 if (m_temporalAAEnabled == temporalAAEnabled)
1252 return;
1253
1254 m_temporalAAEnabled = temporalAAEnabled;
1255 emit temporalAAEnabledChanged();
1256 update();
1257}
1258
1259void QQuick3DSceneEnvironment::setTemporalAAStrength(float strength)
1260{
1261 if (qFuzzyCompare(p1: m_temporalAAStrength, p2: strength))
1262 return;
1263
1264 m_temporalAAStrength = strength;
1265 emit temporalAAStrengthChanged();
1266 update();
1267}
1268
1269void QQuick3DSceneEnvironment::setSpecularAAEnabled(bool enabled)
1270{
1271 if (m_specularAAEnabled == enabled)
1272 return;
1273
1274 m_specularAAEnabled = enabled;
1275 emit specularAAEnabledChanged();
1276 update();
1277}
1278
1279void QQuick3DSceneEnvironment::qmlAppendEffect(QQmlListProperty<QQuick3DEffect> *list, QQuick3DEffect *effect)
1280{
1281 if (effect == nullptr)
1282 return;
1283 QQuick3DSceneEnvironment *self = static_cast<QQuick3DSceneEnvironment *>(list->object);
1284 self->m_effects.push_back(t: effect);
1285
1286 if (effect->parentItem() == nullptr)
1287 effect->setParentItem(self);
1288
1289 for (QQuick3DEffect *e : self->m_effects)
1290 e->effectChainDirty();
1291
1292 self->update();
1293}
1294
1295QQuick3DEffect *QQuick3DSceneEnvironment::qmlEffectAt(QQmlListProperty<QQuick3DEffect> *list, qsizetype index)
1296{
1297 QQuick3DSceneEnvironment *self = static_cast<QQuick3DSceneEnvironment *>(list->object);
1298 return self->m_effects.at(i: index);
1299}
1300
1301qsizetype QQuick3DSceneEnvironment::qmlEffectsCount(QQmlListProperty<QQuick3DEffect> *list)
1302{
1303 QQuick3DSceneEnvironment *self = static_cast<QQuick3DSceneEnvironment *>(list->object);
1304 return self->m_effects.size();
1305}
1306
1307void QQuick3DSceneEnvironment::qmlClearEffects(QQmlListProperty<QQuick3DEffect> *list)
1308{
1309 QQuick3DSceneEnvironment *self = static_cast<QQuick3DSceneEnvironment *>(list->object);
1310 self->m_effects.clear();
1311 self->update();
1312}
1313
1314void QQuick3DSceneEnvironment::setSkyboxBlurAmount(float newSkyboxBlurAmount)
1315{
1316 newSkyboxBlurAmount = qBound(min: 0.0f, val: newSkyboxBlurAmount, max: 1.0f);
1317
1318 if (qFuzzyCompare(p1: m_skyboxBlurAmount, p2: newSkyboxBlurAmount))
1319 return;
1320
1321 m_skyboxBlurAmount = newSkyboxBlurAmount;
1322 emit skyboxBlurAmountChanged();
1323 update();
1324}
1325
1326/*!
1327 \qmlproperty Lightmapper QtQuick3D::SceneEnvironment::lightmapper
1328
1329 When this property is set to a valid Lightmapper object, the settings
1330 specified by the object will be taken into account when baking lightmaps.
1331
1332 The default value is null, which means using default values for all the
1333 baking-related settings.
1334
1335 For more information on how to bake lightmaps, see the \l Lightmapper
1336 documentation.
1337
1338 When lightmaps are not relevant to an application and baked lighting is
1339 never generated, the property and the associated object serve no purpose in
1340 practice.
1341
1342 \sa Model::usedInBakedLighting, Model::bakedLightmap, Light::bakeMode, Lightmapper
1343 */
1344
1345QQuick3DLightmapper *QQuick3DSceneEnvironment::lightmapper() const
1346{
1347 return m_lightmapper;
1348}
1349
1350void QQuick3DSceneEnvironment::setLightmapper(QQuick3DLightmapper *lightmapper)
1351{
1352 if (m_lightmapper == lightmapper)
1353 return;
1354
1355 if (m_lightmapper)
1356 m_lightmapper->disconnect(m_lightmapperSignalConnection);
1357
1358 m_lightmapper = lightmapper;
1359
1360 m_lightmapperSignalConnection = QObject::connect(sender: m_lightmapper, signal: &QQuick3DLightmapper::changed, context: this,
1361 slot: [this] { update(); });
1362
1363 QObject::connect(sender: m_lightmapper, signal: &QObject::destroyed, context: this,
1364 slot: [this](QObject *obj)
1365 {
1366 if (m_lightmapper == obj) {
1367 m_lightmapper = nullptr;
1368 update();
1369 }
1370 });
1371
1372 emit lightmapperChanged();
1373 update();
1374}
1375
1376/*!
1377 \qmlproperty QtQuick3D::CubeMapTexture QtQuick3D::SceneEnvironment::skyBoxCubeMap
1378
1379 This property defines a cubemap to be used as a skybox when the background mode is \c SkyBoxCubeMap.
1380
1381 \since 6.4
1382*/
1383QQuick3DCubeMapTexture *QQuick3DSceneEnvironment::skyBoxCubeMap() const
1384{
1385 return m_skyBoxCubeMap;
1386}
1387
1388void QQuick3DSceneEnvironment::setSkyBoxCubeMap(QQuick3DCubeMapTexture *newSkyBoxCubeMap)
1389{
1390 if (m_skyBoxCubeMap == newSkyBoxCubeMap)
1391 return;
1392
1393 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSceneEnvironment::setSkyBoxCubeMap, newO: newSkyBoxCubeMap, oldO: m_skyBoxCubeMap);
1394
1395 m_skyBoxCubeMap = newSkyBoxCubeMap;
1396 emit skyBoxCubeMapChanged();
1397}
1398
1399void QQuick3DSceneEnvironment::setDebugSettings(QQuick3DDebugSettings *newDebugSettings)
1400{
1401 if (m_debugSettings == newDebugSettings)
1402 return;
1403
1404 if (m_debugSettings)
1405 m_debugSettings->disconnect(m_debugSettingsSignalConnection);
1406
1407 m_debugSettings = newDebugSettings;
1408
1409 m_debugSettingsSignalConnection = QObject::connect(sender: m_debugSettings, signal: &QQuick3DDebugSettings::changed, context: this,
1410 slot: [this] { update(); });
1411 QObject::connect(sender: m_debugSettings, signal: &QObject::destroyed, context: this,
1412 slot: [this](QObject *obj) {
1413 if (m_debugSettings == obj) {
1414 m_debugSettings = nullptr;
1415 update();
1416 }
1417 });
1418
1419 emit debugSettingsChanged();
1420 update();
1421}
1422
1423void QQuick3DSceneEnvironment::setScissorRect(QRect rect)
1424{
1425 if (m_scissorRect == rect)
1426 return;
1427
1428 m_scissorRect = rect;
1429 emit scissorRectChanged();
1430 update();
1431}
1432
1433bool QQuick3DSceneEnvironment::gridEnabled() const
1434{
1435 return m_gridEnabled;
1436}
1437
1438void QQuick3DSceneEnvironment::setGridEnabled(bool newGridEnabled)
1439{
1440 if (m_gridEnabled == newGridEnabled)
1441 return;
1442 m_gridEnabled = newGridEnabled;
1443 update();
1444}
1445
1446float QQuick3DSceneEnvironment::gridScale() const
1447{
1448 return m_gridScale;
1449}
1450
1451void QQuick3DSceneEnvironment::setGridScale(float newGridScale)
1452{
1453 if (qFuzzyCompare(p1: m_gridScale, p2: newGridScale))
1454 return;
1455 m_gridScale = newGridScale;
1456 update();
1457}
1458
1459uint QQuick3DSceneEnvironment::gridFlags() const
1460{
1461 return m_gridFlags;
1462}
1463
1464void QQuick3DSceneEnvironment::setGridFlags(uint newGridFlags)
1465{
1466 if (m_gridFlags == newGridFlags)
1467 return;
1468 m_gridFlags = newGridFlags;
1469 update();
1470}
1471
1472/*!
1473 \qmlproperty bool SceneEnvironment::aoEnabled
1474 \since 6.5
1475
1476 Enable or disable ambient occlusion.
1477
1478 The default value is \c false, which means ambient occlusion is disabled.
1479
1480 \note If \l aoStrength or \ aoDistance is 0, then setting this property to
1481 \c true will also set those values appropriately to make the ambient
1482 occlusion effective.
1483
1484 \note Getting visually good-looking screen space ambient occlusion is
1485 dependent on carefully tuning a number of related parameters, such as \l
1486 aoStrength, \l aoSoftness, \l aoDistance, \l aoDither, \l aoBias, and \l
1487 aoSampleRate.
1488
1489 \sa aoStrength, aoDistance
1490*/
1491
1492bool QQuick3DSceneEnvironment::aoEnabled() const
1493{
1494 return m_aoEnabled;
1495}
1496
1497void QQuick3DSceneEnvironment::setAoEnabled(bool newAoEnabled)
1498{
1499 if (m_aoEnabled == newAoEnabled)
1500 return;
1501
1502 m_aoEnabled = newAoEnabled;
1503
1504 if (m_aoEnabled) {
1505 if (qFuzzyIsNull(f: m_aoStrength))
1506 setAoStrength(100.0f);
1507 if (qFuzzyIsNull(f: m_aoDistance))
1508 setAoDistance(defaultAoDistance());
1509 }
1510
1511 emit aoEnabledChanged();
1512 update();
1513}
1514
1515/*!
1516 \qmlproperty QtQuick3D::Fog QtQuick3D::SceneEnvironment::fog
1517 \since 6.5
1518
1519 When this property is set to a valid \l {QtQuick3D::Fog}{Fog} object, it is
1520 used to configure the renderer's built-in fog support.
1521
1522 The default value is null, which means no fog. This is equivalent to
1523 setting a Fog object with \l{Fog::enabled}{enabled} set to false.
1524
1525 \image fog.jpg
1526
1527 \sa {QtQuick3D::Fog}{Fog}
1528 */
1529
1530QQuick3DFog *QQuick3DSceneEnvironment::fog() const
1531{
1532 return m_fog;
1533}
1534
1535void QQuick3DSceneEnvironment::setFog(QQuick3DFog *fog)
1536{
1537 if (m_fog == fog)
1538 return;
1539
1540 if (m_fog)
1541 m_fog->disconnect(m_fogSignalConnection);
1542
1543 m_fog = fog;
1544
1545 m_fogSignalConnection = QObject::connect(sender: m_fog, signal: &QQuick3DFog::changed, context: this, slot: [this] { update(); });
1546
1547 QObject::connect(sender: m_fog, signal: &QObject::destroyed, context: this,
1548 slot: [this](QObject *obj)
1549 {
1550 if (m_fog == obj) {
1551 m_fog = nullptr;
1552 update();
1553 }
1554 });
1555
1556 emit fogChanged();
1557 update();
1558}
1559
1560QT_END_NAMESPACE
1561

source code of qtquick3d/src/quick3d/qquick3dsceneenvironment.cpp