Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquick3ddirectionallight.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5
8
9#include <QtQuick3DRuntimeRender/private/qssgrenderlight_p.h>
10
12
14
15/*!
16 \qmltype DirectionalLight
17 \inherits Light
18 \inqmlmodule QtQuick3D
19 \brief Defines a directional light in the scene.
20
21 The directional light emits light in one direction from an unidentifiable source located
22 infinitely far away. This is similar to the way sunlight works in real life. A directional
23 light has infinite range and does not diminish.
24
25 If \l {Light::castsShadow}{castsShadow} is enabled, shadows will be parallel to the light
26 direction.
27
28 A directional light effectively have no position, so moving it does not
29 have any effect. The light will always be emitted in the direction of the
30 light's Z axis.
31
32 Rotating the light along its X or Y axis will change the direction of the light emission.
33
34 Scaling a directional light will only have an effect in the following cases:
35 \list
36 \li If Z scale is set to a negative number, the light will be emitted in the opposite direction.
37 \li If the scale of any axis is set to 0, the light will be emitted along the world's Z axis.
38 \note Rotating the light will then have no effect.
39 \endlist
40
41 Let's look at a simple example:
42
43 \qml
44 import QtQuick
45 import QtQuick3D
46 View3D {
47 anchors.fill: parent
48
49 PerspectiveCamera { z: 600 }
50
51 DirectionalLight {
52 }
53
54 Model {
55 source: "#Sphere"
56 scale: Qt.vector3d(4, 4, 4)
57 materials: PrincipledMaterial {
58 baseColor: "#40c060"
59 roughness: 0.1 // make specular highlight visible
60 }
61 }
62 }
63 \endqml
64
65 Here the DirectionalLight uses the default \c white color, emitting in the
66 direction of the DirectionalLight node's Z axis.
67
68 \image directionallight-1.png
69 {Green circle showing directional light emitting along Z axis}
70
71 Rotating 60 degrees around the X axis would lead to the following. Instead
72 of emitting straight in the direction of the Z axis, the light is now
73 pointing 60 degrees "down":
74
75 \qml
76 DirectionalLight {
77 eulerRotation.x: 60
78 }
79 \endqml
80
81 \image directionallight-2.png
82 {Green circle with shading showing rotated directional light}
83
84 For further usage examples, see \l{Qt Quick 3D - Lights Example}.
85
86 \sa PointLight, SpotLight, {Shadow Mapping}
87*/
88
89/*!
90 \qmlproperty real DirectionalLight::csmSplit1
91 \since 6.8
92
93 This property defines where the first cascade of the shadow map split will occur when
94 CSM is active.
95
96 Range: \c{[0.0, 1.0]}
97
98 Default value: \c{0.1}
99
100 \sa csmSplit2, csmSplit3
101 \note This property is only used when DirectionalLight::csmNumSplits is greater than \c{0}.
102*/
103
104/*!
105 \qmlproperty real DirectionalLight::csmSplit2
106 \since 6.8
107
108 This property defines where the second cascade of the shadow map split will occur when
109 CSM is active.
110
111 Range: \c{[0.0, 1.0]}
112
113 Default value: \c{0.25}
114
115 \sa csmSplit1, csmSplit3
116 \note This property is only used when DirectionalLight::csmNumSplits is greater than \c{1}.
117*/
118
119/*!
120 \qmlproperty real DirectionalLight::csmSplit3
121 \since 6.8
122
123 This property defines where the third cascade of the shadow map split will occur when
124 CSM is active.
125
126 Range: \c{[0.0, 1.0]}
127
128 Default value: \c{0.5}
129
130 \sa csmSplit1, csmSplit2
131 \note This property is only used when DirectionalLight::csmNumSplits is greater than \c{2}.
132*/
133
134/*!
135 \qmlproperty int DirectionalLight::csmNumSplits
136 \since 6.8
137
138 This property defines the number of splits the frustum should be split by when
139 rendering the shadowmap. No splits means that the shadowmap will be rendered
140 so that it covers the bounding box of all shadow casting and receiving objects.
141
142 Range: \c{[0, 3]}
143
144 Default value: \c{0}
145
146 \sa csmSplit1, csmSplit2, csmSplit3
147*/
148
149/*!
150 \qmlproperty real DirectionalLight::csmBlendRatio
151 \since 6.8
152
153 This property defines how much of the shadow of any cascade should be blended
154 together with the previous one.
155
156 Range: \c{[0.0, 1.0]}
157
158 Default value: \c{0.05}
159*/
160
161/*!
162 \qmlproperty bool DirectionalLight::lockShadowmapTexels
163 \since 6.9
164
165 When this property is enabled, the shadowmap texels are "locked" in position in the
166 world eliminating shadow edge shimmering at the cost of bigger shadowmap texels.
167 It works by using uniform sized, and texel aligned shadowmaps for each cascade.
168
169 Default value: \c{false}
170*/
171
172QQuick3DDirectionalLight::QQuick3DDirectionalLight(QQuick3DNode *parent)
173 : QQuick3DAbstractLight(*(new QQuick3DNodePrivate(QQuick3DNodePrivate::Type::DirectionalLight)), parent) {}
174
175float QQuick3DDirectionalLight::csmSplit1() const
176{
177 return m_csmSplit1;
178}
179
180float QQuick3DDirectionalLight::csmSplit2() const
181{
182 return m_csmSplit2;
183}
184
185float QQuick3DDirectionalLight::csmSplit3() const
186{
187 return m_csmSplit3;
188}
189
190int QQuick3DDirectionalLight::csmNumSplits() const
191{
192 return m_csmNumSplits;
193}
194
195float QQuick3DDirectionalLight::csmBlendRatio() const
196{
197 return m_csmBlendRatio;
198}
199
200bool QQuick3DDirectionalLight::lockShadowmapTexels() const
201{
202 return m_lockShadowmapTexels;
203}
204
205void QQuick3DDirectionalLight::setCsmSplit1(float newcsmSplit1)
206{
207 newcsmSplit1 = qBound(0.0f, newcsmSplit1, 1.0f);
208 if (qFuzzyCompare(m_csmSplit1, newcsmSplit1))
209 return;
210
211 m_csmSplit1 = newcsmSplit1;
212 emit csmSplit1Changed();
213 m_dirtyFlags.setFlag(QQuick3DAbstractLight::DirtyFlag::ShadowDirty);
214 update();
215}
216
217void QQuick3DDirectionalLight::setCsmSplit2(float newcsmSplit2)
218{
219 newcsmSplit2 = qBound(0.0f, newcsmSplit2, 1.0f);
220 if (qFuzzyCompare(m_csmSplit2, newcsmSplit2))
221 return;
222
223 m_csmSplit2 = newcsmSplit2;
224 emit csmSplit2Changed();
225 m_dirtyFlags.setFlag(QQuick3DAbstractLight::DirtyFlag::ShadowDirty);
226 update();
227}
228
229void QQuick3DDirectionalLight::setCsmSplit3(float newcsmSplit3)
230{
231 newcsmSplit3 = qBound(0.0f, newcsmSplit3, 1.0f);
232 if (qFuzzyCompare(m_csmSplit3, newcsmSplit3))
233 return;
234
235 m_csmSplit3 = newcsmSplit3;
236 emit csmSplit3Changed();
237 m_dirtyFlags.setFlag(QQuick3DAbstractLight::DirtyFlag::ShadowDirty);
238 update();
239}
240
241void QQuick3DDirectionalLight::setCsmNumSplits(int newcsmNumSplits)
242{
243 newcsmNumSplits = qBound(0, newcsmNumSplits, 3);
244 if (m_csmNumSplits == newcsmNumSplits)
245 return;
246
247 m_csmNumSplits = newcsmNumSplits;
248 emit csmNumSplitsChanged();
249 m_dirtyFlags.setFlag(QQuick3DAbstractLight::DirtyFlag::ShadowDirty);
250 update();
251}
252
253void QQuick3DDirectionalLight::setCsmBlendRatio(float newcsmBlendRatio)
254{
255 newcsmBlendRatio = qBound(0.0, newcsmBlendRatio, 1.0);
256 if (m_csmBlendRatio == newcsmBlendRatio)
257 return;
258
259 m_csmBlendRatio = newcsmBlendRatio;
260 emit csmBlendRatioChanged();
261 m_dirtyFlags.setFlag(QQuick3DAbstractLight::DirtyFlag::ShadowDirty);
262 update();
263}
264
265void QQuick3DDirectionalLight::setLockShadowmapTexels(bool newLockShadowmapTexels)
266{
267 if (m_lockShadowmapTexels == newLockShadowmapTexels)
268 return;
269
270 m_lockShadowmapTexels = newLockShadowmapTexels;
271 emit lockShadowmapTexelsChanged();
272 m_dirtyFlags.setFlag(QQuick3DAbstractLight::DirtyFlag::ShadowDirty);
273 update();
274}
275
276QSSGRenderGraphObject *QQuick3DDirectionalLight::updateSpatialNode(QSSGRenderGraphObject *node)
277{
278 if (!node) {
279 markAllDirty();
280 node = new QSSGRenderLight(/* defaults to directional */);
281 }
282
283 if (m_dirtyFlags.testFlag(DirtyFlag::ShadowDirty)) {
284 QSSGRenderLight *light = static_cast<QSSGRenderLight *>(node);
285 light->m_csmSplit1 = m_csmSplit1;
286 light->m_csmSplit2 = m_csmSplit2;
287 light->m_csmSplit3 = m_csmSplit3;
288 light->m_csmNumSplits = m_csmNumSplits;
289 light->m_csmBlendRatio = m_csmBlendRatio;
290 light->m_lockShadowmapTexels = m_lockShadowmapTexels;
291 }
292
293 QQuick3DAbstractLight::updateSpatialNode(node); // Marks the light node dirty if m_dirtyFlags != 0
294
295 return node;
296}
297
298QT_END_NAMESPACE
Combined button and popup list for selecting options.