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
qquick3dlightmapper.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
5
7
8/*!
9 \qmltype Lightmapper
10 \inherits QtObject
11 \inqmlmodule QtQuick3D
12 \brief Specifies lightmap baking settings for a scene.
13 \since 6.4
14
15 Used when baking direct and indirect lighting. Most of these settings are not
16 relevant at other times, such as when using already generated lightmaps to
17 render a scene. The exception is \l source, though this has a sensible default
18 for development.
19
20 On a successfull bake a single file will be generated at the value specified by
21 \l source. This binary file contains the results of the bake, including the
22 per-model lightmaps and the mesh files with lightmap-compatible UVs.
23 The individual model data is accessed via \l BakedLightmap::key.
24
25 The data contained in the resulting lightmap file is all tightly coupled
26 to each other and to the current scene state. This means that any modifications
27 to the original mesh files, Lightmapper settings or other scene changes will
28 require a new bake to be executed to see the updated result.
29
30 \note As of Qt 6.4, lightmap baking is in an early technical preview state.
31 Changes to features, quality, and API are likely to happen in future releases.
32
33 The Lightmapper object works in combination with:
34
35 \list
36 \li \l Model::bakedLightmap and the associated \l BakedLightmap,
37 \li \l Model::usedInBakedLighting and \l Model::texelsPerUnit,
38 \li \l Light::bakeMode,
39 \li the engine's built-in lightmap baker.
40 \endlist
41
42 \sa {Lightmaps and Global Illumination}, {Qt Quick 3D - Baked Lightmap Example}
43 */
44
45/*!
46 \qmlproperty real Lightmapper::opacityThreshold
47
48 The opacity (alpha) threshold below which an object is ignored in ray -
49 mesh intersections when calculating lighting via raytracing. When the
50 opacity falls below the threshold, the model (submesh) will not occlude
51 lights and thus will not generate shadows either.
52
53 The default value is 0.5.
54
55 \note The lightmapper takes the \l{PrincipledMaterial::opacity}{material's
56 opacity} and the \l{PrincipledMaterial::baseColor}{baseColor alpha}
57 combined with the \l{PrincipledMaterial::baseColorMap}{base color map's
58 alpha} into account. Other sources of semi-transparency, such as the
59 opacity map or alpha cut-off settings are ignored during the lightmap
60 baking process.
61 */
62
63/*!
64 \qmlproperty real Lightmapper::bias
65
66 Raycasting bias used during baking. Adapt the value in case artifacts
67 occur, for example in order to reduce undesired shadowing patterns. In many
68 cases the default value is sufficient.
69
70 The default value is 0.005.
71 */
72
73/*!
74 \qmlproperty bool Lightmapper::adaptiveBiasEnabled
75
76 Enables applying an additional, dynamic bias based on the surface normal.
77
78 The default value is true.
79 */
80
81/*!
82 \qmlproperty bool Lightmapper::indirectLightEnabled
83
84 Normally there is no need to change this value. The default value is true.
85 Setting this property to false disables indirect light computation during
86 lightmap baking. Thus the resulting texture maps will only contain direct
87 light information. At run time, the engine will continue to use the maps
88 normally, assuming they contain both direct and indirect lighting.
89 */
90
91/*!
92 \qmlproperty int Lightmapper::samples
93
94 The number of samples per lightmap texel.
95
96 The default value is 256.
97
98 The value heavily affects both the performance and quality of the resulting
99 lightmaps during lightmap baking.
100 */
101
102/*!
103 \qmlproperty int Lightmapper::indirectLightWorkgroupSize
104
105 The size of the sample workgroups. These workgroups are attempted to be
106 executed in parallel. (the exact behavior depends on the number of CPU
107 cores and the QThreadPool configuration)
108
109 The default value is 32. With the default sample count of 256 this means
110 attempting to run 8 groups in parallel per model.
111 */
112
113/*!
114 \qmlproperty int Lightmapper::bounces
115
116 The maximum number of indirect light bounces per sample. The value should
117 at least be 1, no point in indirect light calculation otherwise.
118
119 The default value is 3.
120
121 The value heavily affects both the performance and quality of the resulting
122 lightmaps during lightmap baking.
123*/
124
125/*!
126 \qmlproperty real Lightmapper::indirectLightFactor
127
128 Multiplier for the indirect light amount. While it is the value of 1 (i.e.,
129 not affecting the indirect light amount calculation) that provides the
130 strictly correct rendering results, a slightly higher value can often give
131 better looking results when using the lightmap, even with a lower number of
132 bounces.
133
134 The default value is 1.
135 */
136
137/*!
138 \qmlproperty url Lightmapper::source
139 \since 6.10
140 \default file:lightmaps.bin
141
142 The url for loading the lightmap file at runtime and the output file path
143 on a successful bake.
144
145 When baking, the output path will be deduced from the url and it needs to
146 resolve to a regular file location that is writable. By default the value
147 is \c{file:lightmaps.bin}, which means the file will be put in the current
148 working directory and the final result will instantly appear on a successful
149 bake.
150
151 In the same directory as the output file, a \c{.raw} file is created that
152 contains extra lightmap data used before creating the final lightmap file.
153 This makes it possible to do just denoising without having to bake the whole
154 scene between runs, assuming the \c{.raw} file is present.
155
156 If you want to read the lightmap as a QRC resource you need to embed
157 it in the usual way and add a \c{:/} or \c{qrc:/} prefix to the url.
158 The following example always tries to load the lightmap file embedded via
159 resources. First set the value to a writable location and bake. Then copy the
160 generated file into the source directoy. Then by listing the file in the
161 application's CMake project as a resource under the \c{/lightmaps} PREFIX,
162 lets the build process pick up the file and include it in the executable.
163
164 \qml
165 Lightmapper {
166 source: "qrc:/lightmaps/lightmaps.bin"
167 // will attempt to load from :/lightmaps/lightmaps.bin at runtime
168 // and write a file to lightmaps/lightmaps.bin when baking.
169 }
170 \endqml
171 */
172
173/*!
174 \qmlproperty real Lightmapper::denoiseSigma
175 \since 6.10
176 \default 8
177
178 This property defines the sigma value of the Non-local means based denoiser.
179 This means that the higher this value is the stronger the blurring will be.
180 Try to keep this value as low as possible to avoid losing visual features
181 while still removing the noise.
182*/
183
184/*!
185 \qmlproperty real Lightmapper::texelsPerUnit
186 \since 6.10
187 \default 1
188
189 This property defines the unit to texel scale, meaning a \c{1x1} quad with
190 texelsPerUnit of \c{32} will take up approximately \c{32x32} texels in the
191 lightmap.
192
193 \sa Model::texelsPerUnit
194*/
195
196float QQuick3DLightmapper::opacityThreshold() const
197{
198 return m_opacityThreshold;
199}
200
201float QQuick3DLightmapper::bias() const
202{
203 return m_bias;
204}
205
206bool QQuick3DLightmapper::isAdaptiveBiasEnabled() const
207{
208 return m_adaptiveBias;
209}
210
211bool QQuick3DLightmapper::isIndirectLightEnabled() const
212{
213 return m_indirectLight;
214}
215
216int QQuick3DLightmapper::samples() const
217{
218 return m_samples;
219}
220
221int QQuick3DLightmapper::indirectLightWorkgroupSize() const
222{
223 return m_workgroupSize;
224}
225
226int QQuick3DLightmapper::bounces() const
227{
228 return m_bounces;
229}
230
231float QQuick3DLightmapper::indirectLightFactor() const
232{
233 return m_indirectFactor;
234}
235
236QUrl QQuick3DLightmapper::source() const
237{
238 return m_source;
239}
240
241void QQuick3DLightmapper::setOpacityThreshold(float opacity)
242{
243 if (m_opacityThreshold == opacity)
244 return;
245
246 m_opacityThreshold = opacity;
247 emit opacityThresholdChanged();
248 emit changed();
249}
250
251void QQuick3DLightmapper::setBias(float bias)
252{
253 if (m_bias == bias)
254 return;
255
256 m_bias = bias;
257 emit biasChanged();
258 emit changed();
259}
260
261void QQuick3DLightmapper::setAdaptiveBiasEnabled(bool enabled)
262{
263 if (m_adaptiveBias == enabled)
264 return;
265
266 m_adaptiveBias = enabled;
267 emit adaptiveBiasEnabledChanged();
268 emit changed();
269}
270
271void QQuick3DLightmapper::setIndirectLightEnabled(bool enabled)
272{
273 if (m_indirectLight == enabled)
274 return;
275
276 m_indirectLight = enabled;
277 emit indirectLightEnabledChanged();
278 emit changed();
279}
280
281void QQuick3DLightmapper::setSamples(int count)
282{
283 if (m_samples == count)
284 return;
285
286 m_samples = count;
287 emit samplesChanged();
288 emit changed();
289}
290
291void QQuick3DLightmapper::setIndirectLightWorkgroupSize(int size)
292{
293 if (m_workgroupSize == size)
294 return;
295
296 m_workgroupSize = size;
297 emit indirectLightWorkgroupSizeChanged();
298 emit changed();
299}
300
301void QQuick3DLightmapper::setBounces(int count)
302{
303 if (m_bounces == count)
304 return;
305
306 m_bounces = count;
307 emit bouncesChanged();
308 emit changed();
309}
310
311void QQuick3DLightmapper::setIndirectLightFactor(float factor)
312{
313 if (m_indirectFactor == factor)
314 return;
315
316 m_indirectFactor = factor;
317 emit indirectLightFactorChanged();
318 emit changed();
319}
320
321void QQuick3DLightmapper::setSource(const QUrl &source)
322{
323 if (m_source == source)
324 return;
325
326 m_source = source;
327 emit sourceChanged();
328 emit changed();
329}
330
331float QQuick3DLightmapper::denoiseSigma() const
332{
333 return m_denoiseSigma;
334}
335
336void QQuick3DLightmapper::setDenoiseSigma(float newDenoiseSigma)
337{
338 if (qFuzzyCompare(m_denoiseSigma, newDenoiseSigma))
339 return;
340 m_denoiseSigma = newDenoiseSigma;
341 emit denoiseSigmaChanged();
342 emit changed();
343}
344
345float QQuick3DLightmapper::texelsPerUnit() const
346{
347 return m_texelsPerUnit;
348}
349
350void QQuick3DLightmapper::setTexelsPerUnit(float newTexelsPerUnit)
351{
352 if (qFuzzyCompare(m_texelsPerUnit, newTexelsPerUnit))
353 return;
354 m_texelsPerUnit = newTexelsPerUnit;
355 emit texelsPerUnitChanged();
356 emit changed();
357}
358
359QT_END_NAMESPACE