1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
// Copyright (C) 2019 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "qquick3dpointlight_p.h"
#include "qquick3dobject_p.h"
#include <QtQuick3DRuntimeRender/private/qssgrenderlight_p.h>
#include "qquick3dnode_p_p.h"
QT_BEGIN_NAMESPACE
/*!
\qmltype PointLight
\inherits Light
\inqmlmodule QtQuick3D
\brief Defines a point light in the scene.
The point light can be described as a sphere, emitting light with equal strength in all
directions from the center of the light. This is similar to the way a light bulb emits light.
Rotating or scaling a point light does not have any effect. Moving a point light will change
the position from where the light is emitted.
By default, a point light intensity diminishes according to inverse-square-law. However, the fade-off
(and range) can be controlled with the \l {constantFade}, \l {linearFade}, and
\l quadraticFade properties. Light attenuation is calculated using the formula:
\l {constantFade} + \c distance * (\l {linearFade} * 0.01) + \c distance^2 * (\l {quadraticFade} * 0.0001)
\section2 A simple example: shading a sphere in three different ways
Take a scene containing a sphere in front of a scaled up rectangle in the
background. The default base color of the PrincipledMaterial of the
rectangle is white.
Without any lights and disabling light-related shading for the two meshes,
we get the following:
\qml
import QtQuick
import QtQuick3D
View3D {
anchors.fill: parent
PerspectiveCamera { z: 600 }
Model {
source: "#Rectangle"
scale: Qt.vector3d(10, 10, 10)
z: -100
materials: PrincipledMaterial {
lighting: PrincipledMaterial.NoLighting
}
}
Model {
source: "#Sphere"
scale: Qt.vector3d(2, 2, 2)
materials: PrincipledMaterial {
lighting: PrincipledMaterial.NoLighting
baseColor: "#40c060"
roughness: 0.1
}
}
}
\endqml
\image pointlight-1.png
Adding a directional light, emitting down the Z axis by default, leads to the following:
\qml
import QtQuick
import QtQuick3D
View3D {
anchors.fill: parent
PerspectiveCamera { z: 600 }
DirectionalLight { }
Model {
source: "#Rectangle"
scale: Qt.vector3d(10, 10, 10)
z: -100
materials: PrincipledMaterial { }
}
Model {
source: "#Sphere"
scale: Qt.vector3d(2, 2, 2)
materials: PrincipledMaterial {
baseColor: "#40c060"
roughness: 0.1
}
}
}
\endqml
\image pointlight-2.png
What if we now replace DirectionalLight with:
\qml
PointLight {
z: 300
}
\endqml
The white colored PointLight here is moved on the Z axis so that it is
halfway between the camera and the center of the scene. Unlike
DirectionalLight, the rotation of the PointLight does not matter, whereas
its position is significant. The diminishing intensity is visible here,
especially on the rectangle mesh in the background.
\image pointlight-3.png
For more usage examples, see \l{Qt Quick 3D - Lights Example}.
\sa DirectionalLight, SpotLight, {Shadow Mapping}
*/
/*!
\qmlproperty real PointLight::constantFade
This property is constant factor of the attenuation term of the light.
The default value is 1.0.
*/
/*!
\qmlproperty real PointLight::linearFade
This property increases the rate at which the lighting effect dims the light
in proportion to the distance to the light. The default value is \c 0.0, meaning the light doesn't
have linear fade. The value used here is multiplied by \c 0.01 before being used to
calculate light attenuation.
*/
/*!
\qmlproperty real PointLight::quadraticFade
This property increases the rate at which the lighting effect dims the light
in proportion to the inverse square law. The default value is 1.0 meaning the point light
fade exactly follows the inverse square law i.e. when distance to an object doubles the
light intensity decreases to 1/4th. The value used here is multiplied by \c 0.0001 before
being used to calculate light attenuation.
*/
QQuick3DPointLight::QQuick3DPointLight(QQuick3DNode *parent)
: QQuick3DAbstractLight(*(new QQuick3DNodePrivate(QQuick3DNodePrivate::Type::PointLight)), parent) {}
float QQuick3DPointLight::constantFade() const
{
return m_constantFade;
}
float QQuick3DPointLight::linearFade() const
{
return m_linearFade;
}
float QQuick3DPointLight::quadraticFade() const
{
return m_quadraticFade;
}
void QQuick3DPointLight::setConstantFade(float constantFade)
{
if (qFuzzyCompare(m_constantFade, constantFade))
return;
m_constantFade = constantFade;
m_dirtyFlags.setFlag(DirtyFlag::FadeDirty);
emit constantFadeChanged();
update();
}
void QQuick3DPointLight::setLinearFade(float linearFade)
{
if (qFuzzyCompare(m_linearFade, linearFade))
return;
m_linearFade = linearFade;
m_dirtyFlags.setFlag(DirtyFlag::FadeDirty);
emit linearFadeChanged();
update();
}
void QQuick3DPointLight::setQuadraticFade(float quadraticFade)
{
if (qFuzzyCompare(m_quadraticFade, quadraticFade))
return;
m_quadraticFade = quadraticFade;
m_dirtyFlags.setFlag(DirtyFlag::FadeDirty);
emit quadraticFadeChanged();
update();
}
QSSGRenderGraphObject *QQuick3DPointLight::updateSpatialNode(QSSGRenderGraphObject *node)
{
if (!node) {
markAllDirty();
node = new QSSGRenderLight(QSSGRenderLight::Type::PointLight);
}
QQuick3DAbstractLight::updateSpatialNode(node); // Marks the light node dirty if m_dirtyFlags != 0
QSSGRenderLight *light = static_cast<QSSGRenderLight *>(node);
if (m_dirtyFlags.testFlag(DirtyFlag::FadeDirty)) {
m_dirtyFlags.setFlag(DirtyFlag::FadeDirty, false);
light->m_constantFade = m_constantFade;
light->m_linearFade = m_linearFade;
light->m_quadraticFade = m_quadraticFade;
}
return node;
}
QT_END_NAMESPACE
|