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

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