1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qquick3dfog_p.h"
5
6QT_BEGIN_NAMESPACE
7
8/*!
9 \qmltype Fog
10 \inherits Object
11 \inqmlmodule QtQuick3D
12 \brief Specifies fog settings for a scene.
13 \since 6.5
14
15 When the \l{QQuick3DSceneEnvironment::fog}{fog} property of a \l
16 SceneEnvironment is set to a valid Fog object, the properties are used to
17 configure the rendering of fog.
18
19 \image fog.jpg
20
21 The simple fog provided by this type is implemented by the materials. It is
22 not a post-processing effect, meaning it does not involve additional render
23 passes processing the texture with the output of the \l View3D, but is
24 rather implemented in the fragment shader for each renderable object
25 (submesh of \l Model) with a \l PrincipledMaterial or shaded \l
26 CustomMaterial.
27
28 Fog is configured by a number of properties:
29
30 \list
31
32 \li General settings: \l color and \l density
33
34 \li Depth fog settings: \l depthEnabled, \l depthNear, \l depthFar, \l depthCurve
35
36 \li Height fog settings: \l heightEnabled, \l leastIntenseY, \l mostIntenseY, \l heightCurve
37
38 \li Color transmission settings: \l transmitEnabled, \l transmitCurve
39
40 \endlist
41
42 For example, the following snippet enables depth (but not height) fog using
43 the default fog parameters:
44
45 \qml
46 environment: SceneEnvironment {
47 backgroundMode: SceneEnvironment.Color
48 clearColor: theFog.color
49 fog: Fog {
50 id: theFog
51 enabled: true
52 depthEnabled: true
53 }
54 }
55 \endqml
56
57 Instead of defining the Fog object inline, it is also possible to reference
58 a Fog object by \c id. And since \l ExtendedSceneEnvironment inherits
59 everything from its parent type \l SceneEnvironment, fog can be used with
60 \l ExtendedSceneEnvironment as well:
61
62 \qml
63 Fog {
64 id: theFog
65 enabled: true
66 depthEnabled: true
67 }
68 environment: ExtendedSceneEnvironment {
69 fog: theFog
70 }
71 \endqml
72
73 \sa {Qt Quick 3D - Simple Fog Example}, {Qt Quick 3D - Scene Effects Example}
74 */
75
76/*!
77 \qmlproperty bool Fog::enabled
78
79 Controls whether fog is applied to the scene. The default value is false.
80
81 Enabling depth or height fog has no effect without setting this value to
82 true.
83
84 \sa depthEnabled, heightEnabled
85 */
86
87bool QQuick3DFog::isEnabled() const
88{
89 return m_enabled;
90}
91
92void QQuick3DFog::setEnabled(bool newEnabled)
93{
94 if (m_enabled == newEnabled)
95 return;
96
97 m_enabled = newEnabled;
98 emit enabledChanged();
99 emit changed();
100}
101
102/*!
103 \qmlproperty color Fog::color
104
105 The color of the fog. The default value is "#8099b3"
106
107 \image fog_color_1.jpg
108
109 The same scene with color changed to be more blueish:
110
111 \image fog_color_2.jpg
112
113 \sa density
114 */
115
116QColor QQuick3DFog::color() const
117{
118 return m_color;
119}
120
121void QQuick3DFog::setColor(const QColor &newColor)
122{
123 if (m_color == newColor)
124 return;
125
126 m_color = newColor;
127 emit colorChanged();
128 emit changed();
129}
130
131/*!
132 \qmlproperty float Fog::density
133
134 Controls the fog amount, in practice this is a multiplier in range 0-1. The
135 default value is 1.0. Reducing the value decreases the strength of the fog
136 effect. Applicable only when depthEnabled is set to true.
137
138 The on-screen visual effect may be affected by a number of other settings
139 from \l ExtendedSceneEnvironment, such as tonemapping or glow and bloom.
140 The same density value may give different results depending on what other
141 effects are enabled, and how those are configured.
142
143 An example scene with density set to \c{0.95}:
144
145 \image fog_density_095.jpg
146
147 The same scene with density reduced to \c{0.15}:
148
149 \image fog_density_015.jpg
150
151 \sa color
152 */
153
154float QQuick3DFog::density() const
155{
156 return m_density;
157}
158
159void QQuick3DFog::setDensity(float newDensity)
160{
161 if (qFuzzyCompare(p1: m_density, p2: newDensity))
162 return;
163
164 m_density = newDensity;
165 emit densityChanged();
166 emit changed();
167}
168
169/*!
170 \qmlproperty bool Fog::depthEnabled
171
172 Controls if the fog appears in the distance. The default value is false.
173
174 \sa heightEnabled, enabled, depthNear, depthFar, depthCurve
175 */
176
177bool QQuick3DFog::isDepthEnabled() const
178{
179 return m_depthEnabled;
180}
181
182void QQuick3DFog::setDepthEnabled(bool newDepthEnabled)
183{
184 if (m_depthEnabled == newDepthEnabled)
185 return;
186
187 m_depthEnabled = newDepthEnabled;
188 emit depthEnabledChanged();
189 emit changed();
190}
191
192/*!
193 \qmlproperty float Fog::depthNear
194
195 Starting distance from the camera. The default value is 10.0. Applicable
196 only when depthEnabled is set to true.
197
198 As an example, take this scene, first with a higher depthNear value.
199
200 \image fog_depthnear_higher.jpg
201
202 Decreasing the value of depthNear results in the fog effectively "moving
203 closer" to the camera as it now starts from a smaller distance from the
204 camera:
205
206 \image fog_depthnear_lower.jpg
207
208 \note The scene, including the camera and the models, are expected to be set
209 up accordingly, so that sensible ranges can be defined by properties such
210 as depthNear and depthFar. Do not expect that fog can always be enabled on
211 a scene containing assets imported as-is, without tuning the transforms
212 first. For example, the example screenshots on this page with the
213 \l{https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/Sponza}{Sponza}
214 model are generated after manually applying an additional scale of \c{(100,
215 100, 100)} on the instantiated Sponza component that was generated by the
216 \c balsam tool from the glTF source asset. This then gave a sufficient Z
217 range to get good looking results by tuning the depthNear and depthFar
218 values.
219
220 \sa depthFar, depthEnabled
221 */
222
223float QQuick3DFog::depthNear() const
224{
225 return m_depthNear;
226}
227
228void QQuick3DFog::setDepthNear(float newDepthNear)
229{
230 if (qFuzzyCompare(p1: m_depthNear, p2: newDepthNear))
231 return;
232
233 m_depthNear = newDepthNear;
234 emit depthNearChanged();
235 emit changed();
236}
237
238/*!
239 \qmlproperty float Fog::depthFar
240
241 Ending distance from the camera. The default value is 1000.0. Applicable
242 only when depthEnabled is set to true.
243
244 \note The scene, including the camera and the models, are expected to be set
245 up accordingly, so that sensible ranges can be defined by properties such
246 as depthNear and depthFar. Do not expect that fog can always be enabled on
247 a scene containing assets imported as-is, without tuning the transforms
248 first. For example, the example screenshots on this page with the
249 \l{https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/Sponza}{Sponza}
250 model are generated after manually applying an additional scale of \c{(100,
251 100, 100)} on the instantiated Sponza component that was generated by the
252 \c balsam tool from the glTF source asset. This then gave a sufficient Z
253 range to get good looking results by tuning the depthNear and depthFar
254 values.
255
256 \sa depthNear, depthEnabled
257 */
258
259float QQuick3DFog::depthFar() const
260{
261 return m_depthFar;
262}
263
264void QQuick3DFog::setDepthFar(float newDepthFar)
265{
266 if (qFuzzyCompare(p1: m_depthFar, p2: newDepthFar))
267 return;
268
269 m_depthFar = newDepthFar;
270 emit depthFarChanged();
271 emit changed();
272}
273
274/*!
275 \qmlproperty float Fog::depthCurve
276
277 The default value is 1.0.
278
279 Applicable only when depthEnabled is set to true.
280
281 \sa depthEnabled
282 */
283
284float QQuick3DFog::depthCurve() const
285{
286 return m_depthCurve;
287}
288
289void QQuick3DFog::setDepthCurve(float newDepthCurve)
290{
291 if (qFuzzyCompare(p1: m_depthCurve, p2: newDepthCurve))
292 return;
293
294 m_depthCurve = newDepthCurve;
295 emit depthCurveChanged();
296 emit changed();
297}
298
299/*!
300 \qmlproperty bool Fog::heightEnabled
301
302 Controls if a height fog is enabled. The default value is false.
303
304 \sa depthEnabled, enabled, leastIntenseY, mostIntenseY, heightCurve
305 */
306
307bool QQuick3DFog::isHeightEnabled() const
308{
309 return m_heightEnabled;
310}
311
312void QQuick3DFog::setHeightEnabled(bool newHeightEnabled)
313{
314 if (m_heightEnabled == newHeightEnabled)
315 return;
316
317 m_heightEnabled = newHeightEnabled;
318 emit heightEnabledChanged();
319 emit changed();
320}
321
322/*!
323 \qmlproperty float Fog::leastIntenseY
324
325 Specifies the position (Y coordinate) where the fog is the least intense.
326 The default value is 10.0. Applicable only when heightEnabled is set to
327 true.
328
329 \note By default the value is larger than mostIntenseY. As long as this is
330 true, the fog is rendered top to bottom. When this value is smaller than
331 mostIntenseY, the fog will render bottom to top.
332
333 \note The Y axis points upwards in Qt Quick 3D scenes.
334
335 Pictured here is a scene with height fog enabled (no depth fog), and
336 leastIntenseY set to a value so the fog is only spreading around the bottom
337 of the Sponza scene.
338
339 \image fog_height_least_y_smaller.jpg
340
341 Increasing the value of leastIntenseY makes the fog spread higher since it
342 now effectively starts at a higher Y position in the scene. (remember that
343 the Y axis points upwards)
344
345 \image fog_height_least_y_bigger.jpg
346
347 \note As with depth fog, the scene is expected to be set up accordingly, so
348 that sensible Y coordinate ranges can be defined by leastIntenseY and
349 mostIntenseY. Do not expect that fog can always be enabled on a scene
350 containing assets imported as-is, without tuning the transforms first. For
351 example, the example screenshots on this page with the
352 \l{https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/Sponza}{Sponza}
353 model are generated after manually applying an additional scale of \c{(100,
354 100, 100)} on the instantiated Sponza component that was generated by the
355 \c balsam tool from the glTF source asset.
356
357 \sa mostIntenseY, heightEnabled
358 */
359
360float QQuick3DFog::leastIntenseY() const
361{
362 return m_leastIntenseY;
363}
364
365void QQuick3DFog::setLeastIntenseY(float newLeastIntenseY)
366{
367 if (qFuzzyCompare(p1: m_leastIntenseY, p2: newLeastIntenseY))
368 return;
369
370 m_leastIntenseY = newLeastIntenseY;
371 emit leastIntenseYChanged();
372 emit changed();
373}
374
375/*!
376 \qmlproperty float Fog::mostIntenseY
377
378 Specifies the position (Y coordinate) where the fog is the most intense.
379 The default value is 0. Applicable only when heightEnabled is set to true.
380
381 \note By default the value is smaller than leastIntenseY. As long as this is
382 true, the fog is rendered top to bottom. When this value is larger than
383 leastIntenseY, the fog will render bottom to top.
384
385 \note The Y axis points upwards in Qt Quick 3D scenes.
386
387 \note As with depth fog, the scene is expected to be set up accordingly, so
388 that sensible Y coordinate ranges can be defined by leastIntenseY and
389 mostIntenseY. Do not expect that fog can always be enabled on a scene
390 containing assets imported as-is, without tuning the transforms first. For
391 example, the example screenshots on this page with the
392 \l{https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/Sponza}{Sponza}
393 model are generated after manually applying an additional scale of \c{(100,
394 100, 100)} on the instantiated Sponza component that was generated by the
395 \c balsam tool from the glTF source asset.
396
397 \sa leastIntenseY, heightEnabled
398 */
399
400float QQuick3DFog::mostIntenseY() const
401{
402 return m_mostIntenseY;
403}
404
405void QQuick3DFog::setMostIntenseY(float newMostIntenseY)
406{
407 if (qFuzzyCompare(p1: m_mostIntenseY, p2: newMostIntenseY))
408 return;
409
410 m_mostIntenseY = newMostIntenseY;
411 emit mostIntenseYChanged();
412 emit changed();
413}
414
415/*!
416 \qmlproperty float Fog::heightCurve
417
418 Specifies the intensity of the height fog. The default value is 1.0.
419 Applicable only when heightEnabled is set to true.
420
421 \sa heightEnabled
422 */
423
424float QQuick3DFog::heightCurve() const
425{
426 return m_heightCurve;
427}
428
429void QQuick3DFog::setHeightCurve(float newHeightCurve)
430{
431 if (qFuzzyCompare(p1: m_heightCurve, p2: newHeightCurve))
432 return;
433
434 m_heightCurve = newHeightCurve;
435 emit heightCurveChanged();
436 emit changed();
437}
438
439/*!
440 \qmlproperty bool Fog::transmitEnabled
441
442 Controls if the fog has a light transmission effect. The default value is
443 false.
444 */
445
446bool QQuick3DFog::isTransmitEnabled() const
447{
448 return m_transmitEnabled;
449}
450
451void QQuick3DFog::setTransmitEnabled(bool newTransmitEnabled)
452{
453 if (m_transmitEnabled == newTransmitEnabled)
454 return;
455
456 m_transmitEnabled = newTransmitEnabled;
457 emit transmitEnabledChanged();
458 emit changed();
459}
460
461/*!
462 \qmlproperty float Fog::transmitCurve
463
464 Intensity of the light transmission effect. The default value is 1.0.
465 Applicable only when transmitEnabled is set to true.
466 */
467
468float QQuick3DFog::transmitCurve() const
469{
470 return m_transmitCurve;
471}
472
473void QQuick3DFog::setTransmitCurve(float newTransmitCurve)
474{
475 if (qFuzzyCompare(p1: m_transmitCurve, p2: newTransmitCurve))
476 return;
477
478 m_transmitCurve = newTransmitCurve;
479 emit transmitCurveChanged();
480 emit changed();
481}
482
483QT_END_NAMESPACE
484

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