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
qquick3ddefaultmaterial.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/qssgrenderdefaultmaterial_p.h>
10#include <QtQuick3DUtils/private/qssgutils_p.h>
11
13
14
15/*!
16 \qmltype DefaultMaterial
17 \inherits Material
18 \inqmlmodule QtQuick3D
19 \brief Lets you define a material for 3D items using the specular/glossiness workflow.
20
21 \deprecated [6.4] Prefer using the \l PrincipledMaterial or \l SpecularGlossyMaterial instead.
22
23 \warning This material is only provided for compatibility reasons, and should not be used in new code.
24 Prefer using the \l SpecularGlossyMaterial for creating materials using the specular/glossiness
25 workflow or the \l PrincipledMaterial for creating materials using the metal/roughness workflow.
26
27 Before a Model can be rendered in a scene, it must have at least one material attached
28 to it that describes how the mesh should be shaded. The DefaultMaterial is an easy to
29 use material that lets you describe your material using a specular/glossiness type workflow.
30 The material has sensible default and can be used to shade a model without changing any properties.
31
32 \section1 Specular/Glossiness workflow
33
34 The Default material provides a way to create materials using a specular/glossiness
35 type workflow. The main properties of the material are controlled through the
36 \l {DefaultMaterial::specularMap} {specular}, \l {DefaultMaterial::roughnessMap} {roughness},
37 and the \l {DefaultMaterial::diffuseMap} {diffuse color} property.
38
39 \section2 Specular
40
41 The \l {DefaultMaterial::specularMap} {specular reflectivity} describes the specular
42 amount and color of an object's surface. For reflective materials the main color
43 contribution, comes from this property.
44
45 \section2 Glossiness (Roughness)
46
47 The glossiness of a surface depends on how smooth or irregular the surface is.
48 A smooth surface will have a more intense light reflection then a rough surface, where
49 the light reflection will be more spread out. In the Default material the material's glossiness
50 is controlled through the \l {DefaultMaterial::roughnessMap} {roughness} property.
51
52 \section2 Diffuse color
53
54 The \l {DefaultMaterial::diffuseMap} {diffuse color} property describes the basic color
55 of the material, and unlike the \l {PrincipledMaterial}'s base color, the diffuse color
56 does not contain any information about the material reflectance. However, for
57 reflective surfaces the diffuse color should be set to a black tint, as that will allow
58 for the specular color to contribute.
59*/
60
61/*!
62 \qmlproperty enumeration DefaultMaterial::lighting
63
64 This property defines which lighting method is used when generating this
65 material.
66
67 The default value is \c DefaultMaterial.FragmentLighting
68
69 When using \c DefaultMaterial.FragmentLighting, diffuse and specular lighting are
70 calculated for each rendered pixel. Certain effects (such as a Fresnel or bump map) require
71 \c DefaultMaterial.FragmentLighting to work.
72
73 When using \c DefaultMaterial.NoLighting no lighting is calculated. This
74 mode is (predictably) very fast, and quite effective when image maps are
75 used that do not need to be shaded by lighting.
76
77 \value DefaultMaterial.NoLighting No lighting is calculated.
78 \value DefaultMaterial.FragmentLighting Per-fragment lighting is calculated.
79*/
80
81/*!
82 \qmlproperty enumeration DefaultMaterial::blendMode
83
84 This property determines how the colors of the model rendered blend with
85 those behind it.
86
87 \value DefaultMaterial.SourceOver Default blend mode. Opaque objects
88 occlude objects behind them. This default mode does not guarantee alpha
89 blending in the rendering pipeline on its own for models that use this
90 material, but rather makes the decision dependent on a number of factors:
91 if the object's and material's total opacity is \c{1.0} and there are no
92 texture maps in the material with semi-transparent pixels in them, then the
93 model is treated as opaque, meaning it is rendered with depth testing and
94 depth write enabled, together with other opaque objects, with blending
95 disabled. Otherwise the model is treated as semi-transparent, and is
96 rendered after the opaque objects, together with other semi-transparent
97 objects in a back-to-front order based on their center's distance from the
98 camera, with alpha blending enabled.
99
100 \value DefaultMaterial.Screen Colors are blended using an inverted
101 multiply, producing a lighter result. This blend mode is order-independent;
102 if you are using semi-opaque objects and experiencing \e popping as faces
103 or models sort differently, using Screen blending is one way to produce
104 results without popping.
105
106 \value DefaultMaterial.Multiply Colors are blended using a multiply,
107 producing a darker result. This blend mode is also order-independent.
108
109 \sa {Qt Quick 3D Architecture}
110*/
111
112/*!
113 \qmlproperty color DefaultMaterial::diffuseColor
114
115 This property determines the diffuse color (albedo) for the material. Setting the
116 diffuse color to a black tint will create a purely-specular material (e.g. metals or mirrors).
117 */
118
119/*!
120 \qmlproperty Texture DefaultMaterial::diffuseMap
121
122 This property defines a Texture to apply to the material. Using Texture
123 with transparency will also apply the alpha channel as an opacity map.
124 */
125
126/*!
127 \qmlproperty vector3d DefaultMaterial::emissiveFactor
128
129 This property determines the color of self-illumination for this material.
130 If an emissive map is set, the x, y, and z components are used as factors
131 (multipliers) for the R, G and B channels of the texture, respectively.
132 The default value is (0, 0, 0) and it means no emissive contribution at all.
133
134 \note Setting the lightingMode to DefaultMaterial.NoLighting means emissive
135 Factor does not have an effect on the scene.
136*/
137
138/*!
139 \qmlproperty Texture DefaultMaterial::emissiveMap
140
141 This property sets a RGB Texture to be used to specify the intensity of the
142 emissive color.
143
144 \sa emissiveFactor
145*/
146
147/*!
148 \qmlproperty Texture DefaultMaterial::specularReflectionMap
149
150 This property sets a Texture used for specular highlights on the material.
151
152 This is typically used to perform environment mapping: as the model is
153 rotated, the map will appear as though it is reflecting from the
154 environment. For this to work as expected, the Texture's
155 \l{Texture::mappingMode}{mappingMode} needs to be set to
156 Texture.Environment. Specular reflection maps are an easy way to add a
157 high-quality look with a relatively low cost.
158
159 \note Associating a \l{SceneEnvironment::lightProbe}{light probe} with the
160 \l SceneEnvironment, and thus relying on image-based lighting, can achieve
161 similar environmental reflection effects. Light probes are however a
162 conceptually different, and when it comes to performance, potentially more
163 expensive solution. Each approaches have their own specific uses, and the
164 one to use needs to be decided on a case by case basis. When it comes to
165 the Texture set to the property, specularReflectionMap has an advantage,
166 because it presents no limitations and supports all types of textures,
167 including ones that source their data from a Qt Quick sub-scene via
168 \l{Texture::sourceItem}{sourceItem}.
169
170 \note Crisp images cause your material to look very glossy; the more you
171 blur your image the softer your material will appear.
172
173 \sa Texture::mappingMode
174*/
175
176/*!
177 \qmlproperty Texture DefaultMaterial::specularMap
178
179 This property defines a RGB Texture to modulate the amount and the color of
180 specularity across the surface of the material. These values are multiplied
181 by the specularAmount.
182*/
183
184/*!
185 \qmlproperty enumeration DefaultMaterial::specularModel
186
187 This property determines which functions are used to calculate specular
188 highlights for lights in the scene.
189
190 \value DefaultMaterial.Default Specular lighting uses default lighting model.
191 \value DefaultMaterial.KGGX Specular lighting uses GGX lighting model.
192*/
193
194/*!
195 \qmlproperty color DefaultMaterial::specularTint
196
197 This property defines a color used to adjust the specular reflections.
198 Use white for no effect
199*/
200
201/*!
202 \qmlproperty real DefaultMaterial::indexOfRefraction
203
204 This property controls what angles of reflections are affected by the
205 fresnelPower. The default is \c 1.45. The value must be greater or equal to \c 1.0.
206 \note No known material in the world have ior much greater than \c 3.0.
207*/
208
209/*!
210 \qmlproperty real DefaultMaterial::fresnelPower
211
212 This property decreases head-on reflections (looking directly at the
213 surface) while maintaining reflections seen at grazing angles.
214 The default value is \c 0 disabling the fresnel effect.
215*/
216
217/*!
218 \qmlproperty real DefaultMaterial::specularAmount
219
220 This property controls the strength of specularity (highlights and
221 reflections). The default value is \c 0 disabling the specularity. The range is [0.0, 1.0].
222
223 \note This property does not affect the \l specularReflectionMap, but does
224 affect the amount of reflections from a scene's SceneEnvironment::lightProbe.
225
226 \note Unless your mesh is high resolution, you may need to use
227 \c DefaultMaterial.FragmentLighting to get good specular highlights from scene
228 lights.
229*/
230
231/*!
232 \qmlproperty real DefaultMaterial::specularRoughness
233
234 This property controls the size of the specular highlight generated from
235 lights, and the clarity of reflections in general. Larger values increase
236 the roughness, softening specular highlights and blurring reflections.
237 The range is [0.0, 1.0]. The default value is 0.
238*/
239
240/*!
241 \qmlproperty Texture DefaultMaterial::roughnessMap
242
243 This property defines a Texture to control the specular roughness of the
244 material. If the texture contains multiple channels(RGBA), then the correct channel
245 can be set using the roughnessChannel property.
246*/
247
248/*!
249 \qmlproperty enumeration DefaultMaterial::roughnessChannel
250
251 This property defines the texture channel used to read the roughness value from roughnessMap.
252 The default value is \c Material.R.
253
254 \value Material.R Read value from texture R channel.
255 \value Material.G Read value from texture G channel.
256 \value Material.B Read value from texture B channel.
257 \value Material.A Read value from texture A channel.
258*/
259
260/*!
261 \qmlproperty real DefaultMaterial::opacity
262
263 This property drops the opacity of just this material, separate from the model.
264 The default is \c 1.0. The range is [0.0, 1.0].
265*/
266
267/*!
268 \qmlproperty Texture DefaultMaterial::opacityMap
269
270 This property defines a Texture used to control the opacity differently for
271 different parts of the material.
272*/
273
274/*!
275 \qmlproperty enumeration DefaultMaterial::opacityChannel
276
277 This property defines the texture channel used to read the opacity value from opacityMap.
278 The default value is \c Material.A.
279
280 \value Material.R Read value from texture R channel.
281 \value Material.G Read value from texture G channel.
282 \value Material.B Read value from texture B channel.
283 \value Material.A Read value from texture A channel.
284*/
285
286/*!
287 \qmlproperty Texture DefaultMaterial::bumpMap
288
289 This property defines a grayscale Texture to simulate fine geometry
290 displacement across the surface of the material. Brighter pixels indicate
291 raised regions. The amount of the effect is controlled by the
292 \l bumpAmount property.
293
294 \note bump maps will not affect the silhouette of a model.
295
296*/
297
298/*!
299 \qmlproperty real DefaultMaterial::bumpAmount
300
301 This property controls the amount of simulated displacement for the
302 \l bumpMap or \l normalMap. The default value is \c 0 disabling the bump effect.
303 The range is [0, 1].
304
305*/
306
307/*!
308 \qmlproperty Texture DefaultMaterial::normalMap
309
310 This property defines a RGB image used to simulate fine geometry
311 displacement across the surface of the material. The RGB channels indicate
312 XYZ normal deviations. The amount of the effect is controlled by the
313 \l bumpAmount property.
314
315 \note Normal maps will not affect the silhouette of a model.
316*/
317
318/*!
319 \qmlproperty Texture DefaultMaterial::translucencyMap
320
321 This property defines a grayscale Texture controlling how much light can
322 pass through the material from behind.
323*/
324
325/*!
326 \qmlproperty enumeration DefaultMaterial::translucencyChannel
327
328 This property defines the texture channel used to read the translucency value from translucencyMap.
329 The default value is \c Material.A.
330
331 \value Material.R Read value from texture R channel.
332 \value Material.G Read value from texture G channel.
333 \value Material.B Read value from texture B channel.
334 \value Material.A Read value from texture A channel.
335*/
336
337/*!
338 \qmlproperty real DefaultMaterial::translucentFalloff
339
340 This property defines the amount of falloff for the translucency based on the
341 angle of the normals of the object to the light source.
342*/
343
344/*!
345 \qmlproperty real DefaultMaterial::diffuseLightWrap
346
347 This property determines the amount of light wrap for the translucency map.
348 A value of 0 will not wrap the light at all, while a value of 1 will wrap
349 the light all around the object.
350*/
351
352/*!
353 \qmlproperty bool DefaultMaterial::vertexColorsEnabled
354
355 When this property is enabled, the material will use vertex colors from the
356 mesh. These will be multiplied by any other colors specified for the
357 material.
358*/
359
360/*!
361 \qmlproperty real DefaultMaterial::pointSize
362
363 This property determines the size of the points rendered, when the geometry
364 is using a primitive type of points. The default value is 1.0. This
365 property is not relevant when rendering other types of geometry, such as,
366 triangle meshes.
367
368 \warning Point sizes other than 1 may not be supported at run time,
369 depending on the underyling graphics API. For example, setting a size other
370 than 1 has no effect with Direct 3D.
371*/
372
373/*!
374 \qmlproperty real DefaultMaterial::lineWidth
375
376 This property determines the width of the lines rendered, when the geometry
377 is using a primitive type of lines or line strips. The default value is
378 1.0. This property is not relevant when rendering other types of geometry,
379 such as, triangle meshes.
380
381 \warning Line widths other than 1 may not be suported at run time,
382 depending on the underlying graphics API. When that is the case, the
383 request to change the width is ignored. For example, none of the following
384 can be expected to support wide lines: Direct3D, Metal, OpenGL with core
385 profile contexts.
386
387 \note Unlike most other material properties, the line width is under the
388 hood baked in to a graphics pipeline object, similarly to blendMode.
389 Therefore, a different value leads to having to create a new pipeline
390 object, which over time can become costly (performance and resource usage)
391 if the property is frequently changed to many different values. For
392 example, animating this property is possible, but should be avoided.
393 */
394
395QQuick3DDefaultMaterial::QQuick3DDefaultMaterial(QQuick3DObject *parent)
396 : QQuick3DMaterial(*(new QQuick3DObjectPrivate(QQuick3DObjectPrivate::Type::DefaultMaterial)), parent)
397 , m_diffuseColor(Qt::white)
398 , m_specularTint(Qt::white)
399{}
400
401QQuick3DDefaultMaterial::~QQuick3DDefaultMaterial()
402{
403}
404
405QQuick3DDefaultMaterial::Lighting QQuick3DDefaultMaterial::lighting() const
406{
407 return m_lighting;
408}
409
410QQuick3DDefaultMaterial::BlendMode QQuick3DDefaultMaterial::blendMode() const
411{
412 return m_blendMode;
413}
414
415QColor QQuick3DDefaultMaterial::diffuseColor() const
416{
417 return m_diffuseColor;
418}
419
420QQuick3DTexture *QQuick3DDefaultMaterial::diffuseMap() const
421{
422 return m_diffuseMap;
423}
424
425QVector3D QQuick3DDefaultMaterial::emissiveFactor() const
426{
427 return m_emissiveFactor;
428}
429
430QQuick3DTexture *QQuick3DDefaultMaterial::emissiveMap() const
431{
432 return m_emissiveMap;
433}
434
435QQuick3DTexture *QQuick3DDefaultMaterial::specularReflectionMap() const
436{
437 return m_specularReflectionMap;
438}
439
440QQuick3DTexture *QQuick3DDefaultMaterial::specularMap() const
441{
442 return m_specularMap;
443}
444
445QQuick3DDefaultMaterial::SpecularModel QQuick3DDefaultMaterial::specularModel() const
446{
447 return m_specularModel;
448}
449
450QColor QQuick3DDefaultMaterial::specularTint() const
451{
452 return m_specularTint;
453}
454
455float QQuick3DDefaultMaterial::indexOfRefraction() const
456{
457 return m_indexOfRefraction;
458}
459
460float QQuick3DDefaultMaterial::fresnelPower() const
461{
462 return m_fresnelPower;
463}
464
465float QQuick3DDefaultMaterial::specularAmount() const
466{
467 return m_specularAmount;
468}
469
470float QQuick3DDefaultMaterial::specularRoughness() const
471{
472 return m_specularRoughness;
473}
474
475QQuick3DTexture *QQuick3DDefaultMaterial::roughnessMap() const
476{
477 return m_roughnessMap;
478}
479
480float QQuick3DDefaultMaterial::opacity() const
481{
482 return m_opacity;
483}
484
485QQuick3DTexture *QQuick3DDefaultMaterial::opacityMap() const
486{
487 return m_opacityMap;
488}
489
490QQuick3DTexture *QQuick3DDefaultMaterial::bumpMap() const
491{
492 return m_bumpMap;
493}
494
495float QQuick3DDefaultMaterial::bumpAmount() const
496{
497 return m_bumpAmount;
498}
499
500QQuick3DTexture *QQuick3DDefaultMaterial::normalMap() const
501{
502 return m_normalMap;
503}
504
505QQuick3DTexture *QQuick3DDefaultMaterial::translucencyMap() const
506{
507 return m_translucencyMap;
508}
509
510float QQuick3DDefaultMaterial::translucentFalloff() const
511{
512 return m_translucentFalloff;
513}
514
515float QQuick3DDefaultMaterial::diffuseLightWrap() const
516{
517 return m_diffuseLightWrap;
518}
519
520bool QQuick3DDefaultMaterial::vertexColorsEnabled() const
521{
522 return m_vertexColorsEnabled;
523}
524
525QQuick3DMaterial::TextureChannelMapping QQuick3DDefaultMaterial::roughnessChannel() const
526{
527 return m_roughnessChannel;
528}
529
530QQuick3DMaterial::TextureChannelMapping QQuick3DDefaultMaterial::opacityChannel() const
531{
532 return m_opacityChannel;
533}
534
535QQuick3DMaterial::TextureChannelMapping QQuick3DDefaultMaterial::translucencyChannel() const
536{
537 return m_translucencyChannel;
538}
539
540float QQuick3DDefaultMaterial::pointSize() const
541{
542 return m_pointSize;
543}
544
545float QQuick3DDefaultMaterial::lineWidth() const
546{
547 return m_lineWidth;
548}
549
550void QQuick3DDefaultMaterial::markAllDirty()
551{
552 m_dirtyAttributes = 0xffffffff;
553 QQuick3DMaterial::markAllDirty();
554}
555
556
557void QQuick3DDefaultMaterial::setLighting(QQuick3DDefaultMaterial::Lighting lighting)
558{
559 if (m_lighting == lighting)
560 return;
561
562 m_lighting = lighting;
563 emit lightingChanged(m_lighting);
564 markDirty(LightingModeDirty);
565}
566
567void QQuick3DDefaultMaterial::setBlendMode(QQuick3DDefaultMaterial::BlendMode blendMode)
568{
569 if (m_blendMode == blendMode)
570 return;
571
572 m_blendMode = blendMode;
573 emit blendModeChanged(m_blendMode);
574 markDirty(BlendModeDirty);
575}
576
577void QQuick3DDefaultMaterial::setDiffuseColor(QColor diffuseColor)
578{
579 if (m_diffuseColor == diffuseColor)
580 return;
581
582 m_diffuseColor = diffuseColor;
583 emit diffuseColorChanged(m_diffuseColor);
584 markDirty(DiffuseDirty);
585}
586
587void QQuick3DDefaultMaterial::setDiffuseMap(QQuick3DTexture *diffuseMap)
588{
589 if (m_diffuseMap == diffuseMap)
590 return;
591
592 QQuick3DObjectPrivate::attachWatcher(this, &QQuick3DDefaultMaterial::setDiffuseMap, diffuseMap, m_diffuseMap);
593
594 m_diffuseMap = diffuseMap;
595 emit diffuseMapChanged(m_diffuseMap);
596 markDirty(DiffuseDirty);
597}
598
599void QQuick3DDefaultMaterial::setEmissiveFactor(QVector3D emissiveFactor)
600{
601 if (m_emissiveFactor == emissiveFactor)
602 return;
603
604 m_emissiveFactor = emissiveFactor;
605 emit emissiveFactorChanged(m_emissiveFactor);
606 markDirty(EmissiveDirty);
607}
608
609void QQuick3DDefaultMaterial::setEmissiveMap(QQuick3DTexture *emissiveMap)
610{
611 if (m_emissiveMap == emissiveMap)
612 return;
613
614 QQuick3DObjectPrivate::attachWatcher(this, &QQuick3DDefaultMaterial::setEmissiveMap, emissiveMap, m_emissiveMap);
615
616 m_emissiveMap = emissiveMap;
617 emit emissiveMapChanged(m_emissiveMap);
618 markDirty(EmissiveDirty);
619}
620
621void QQuick3DDefaultMaterial::setSpecularReflectionMap(QQuick3DTexture *specularReflectionMap)
622{
623 if (m_specularReflectionMap == specularReflectionMap)
624 return;
625
626 QQuick3DObjectPrivate::attachWatcher(this, &QQuick3DDefaultMaterial::setSpecularReflectionMap, specularReflectionMap, m_specularReflectionMap);
627
628 m_specularReflectionMap = specularReflectionMap;
629 emit specularReflectionMapChanged(m_specularReflectionMap);
630 markDirty(SpecularDirty);
631}
632
633void QQuick3DDefaultMaterial::setSpecularMap(QQuick3DTexture *specularMap)
634{
635 if (m_specularMap == specularMap)
636 return;
637
638 QQuick3DObjectPrivate::attachWatcher(this, &QQuick3DDefaultMaterial::setSpecularMap, specularMap, m_specularMap);
639
640 m_specularMap = specularMap;
641 emit specularMapChanged(m_specularMap);
642 markDirty(SpecularDirty);
643}
644
645void QQuick3DDefaultMaterial::setSpecularModel(QQuick3DDefaultMaterial::SpecularModel specularModel)
646{
647 if (m_specularModel == specularModel)
648 return;
649
650 m_specularModel = specularModel;
651 emit specularModelChanged(m_specularModel);
652 markDirty(SpecularDirty);
653}
654
655void QQuick3DDefaultMaterial::setSpecularTint(QColor specularTint)
656{
657 if (m_specularTint == specularTint)
658 return;
659
660 m_specularTint = specularTint;
661 emit specularTintChanged(m_specularTint);
662 markDirty(SpecularDirty);
663}
664
665void QQuick3DDefaultMaterial::setIndexOfRefraction(float indexOfRefraction)
666{
667 if (qFuzzyCompare(m_indexOfRefraction, indexOfRefraction))
668 return;
669
670 m_indexOfRefraction = indexOfRefraction;
671 emit indexOfRefractionChanged(m_indexOfRefraction);
672 markDirty(SpecularDirty);
673}
674
675void QQuick3DDefaultMaterial::setFresnelPower(float fresnelPower)
676{
677 if (qFuzzyCompare(m_fresnelPower, fresnelPower))
678 return;
679
680 m_fresnelPower = fresnelPower;
681 emit fresnelPowerChanged(m_fresnelPower);
682 markDirty(SpecularDirty);
683}
684
685void QQuick3DDefaultMaterial::setSpecularAmount(float specularAmount)
686{
687 if (qFuzzyCompare(m_specularAmount, specularAmount))
688 return;
689
690 m_specularAmount = specularAmount;
691 emit specularAmountChanged(m_specularAmount);
692 markDirty(SpecularDirty);
693}
694
695void QQuick3DDefaultMaterial::setSpecularRoughness(float specularRoughness)
696{
697 if (qFuzzyCompare(m_specularRoughness, specularRoughness))
698 return;
699
700 m_specularRoughness = specularRoughness;
701 emit specularRoughnessChanged(m_specularRoughness);
702 markDirty(SpecularDirty);
703}
704
705void QQuick3DDefaultMaterial::setRoughnessMap(QQuick3DTexture *roughnessMap)
706{
707 if (m_roughnessMap == roughnessMap)
708 return;
709
710 QQuick3DObjectPrivate::attachWatcher(this, &QQuick3DDefaultMaterial::setRoughnessMap, roughnessMap, m_roughnessMap);
711
712 m_roughnessMap = roughnessMap;
713 emit roughnessMapChanged(m_roughnessMap);
714 markDirty(SpecularDirty);
715}
716
717void QQuick3DDefaultMaterial::setOpacity(float opacity)
718{
719 if (qFuzzyCompare(m_opacity, opacity))
720 return;
721
722 if (opacity > 1.0f)
723 opacity = 1.0f;
724
725 if (opacity < 0.0f)
726 opacity = 0.0f;
727
728 m_opacity = opacity;
729 emit opacityChanged(m_opacity);
730 markDirty(OpacityDirty);
731}
732
733void QQuick3DDefaultMaterial::setOpacityMap(QQuick3DTexture *opacityMap)
734{
735 if (m_opacityMap == opacityMap)
736 return;
737
738 QQuick3DObjectPrivate::attachWatcher(this, &QQuick3DDefaultMaterial::setOpacityMap, opacityMap, m_opacityMap);
739
740 m_opacityMap = opacityMap;
741 emit opacityMapChanged(m_opacityMap);
742 markDirty(OpacityDirty);
743}
744
745void QQuick3DDefaultMaterial::setBumpMap(QQuick3DTexture *bumpMap)
746{
747 if (m_bumpMap == bumpMap)
748 return;
749
750 QQuick3DObjectPrivate::attachWatcher(this, &QQuick3DDefaultMaterial::setBumpMap, bumpMap, m_bumpMap);
751
752 m_bumpMap = bumpMap;
753 emit bumpMapChanged(m_bumpMap);
754 markDirty(BumpDirty);
755}
756
757void QQuick3DDefaultMaterial::setBumpAmount(float bumpAmount)
758{
759 if (qFuzzyCompare(m_bumpAmount, bumpAmount))
760 return;
761
762 m_bumpAmount = bumpAmount;
763 emit bumpAmountChanged(m_bumpAmount);
764 markDirty(BumpDirty);
765}
766
767void QQuick3DDefaultMaterial::setNormalMap(QQuick3DTexture *normalMap)
768{
769 if (m_normalMap == normalMap)
770 return;
771
772 QQuick3DObjectPrivate::attachWatcher(this, &QQuick3DDefaultMaterial::setNormalMap, normalMap, m_normalMap);
773
774 m_normalMap = normalMap;
775 emit normalMapChanged(m_normalMap);
776 markDirty(NormalDirty);
777}
778
779void QQuick3DDefaultMaterial::setTranslucencyMap(QQuick3DTexture *translucencyMap)
780{
781 if (m_translucencyMap == translucencyMap)
782 return;
783
784 QQuick3DObjectPrivate::attachWatcher(this, &QQuick3DDefaultMaterial::setTranslucencyMap, translucencyMap, m_translucencyMap);
785
786 m_translucencyMap = translucencyMap;
787 emit translucencyMapChanged(m_translucencyMap);
788 markDirty(TranslucencyDirty);
789}
790
791void QQuick3DDefaultMaterial::setTranslucentFalloff(float translucentFalloff)
792{
793 if (qFuzzyCompare(m_translucentFalloff, translucentFalloff))
794 return;
795
796 m_translucentFalloff = translucentFalloff;
797 emit translucentFalloffChanged(m_translucentFalloff);
798 markDirty(TranslucencyDirty);
799}
800
801void QQuick3DDefaultMaterial::setDiffuseLightWrap(float diffuseLightWrap)
802{
803 if (qFuzzyCompare(m_diffuseLightWrap, diffuseLightWrap))
804 return;
805
806 m_diffuseLightWrap = diffuseLightWrap;
807 emit diffuseLightWrapChanged(m_diffuseLightWrap);
808 markDirty(DiffuseDirty);
809}
810
811void QQuick3DDefaultMaterial::setVertexColorsEnabled(bool vertexColors)
812{
813 if (m_vertexColorsEnabled == vertexColors)
814 return;
815
816 m_vertexColorsEnabled = vertexColors;
817 emit vertexColorsEnabledChanged(m_vertexColorsEnabled);
818 markDirty(VertexColorsDirty);
819}
820
821void QQuick3DDefaultMaterial::setRoughnessChannel(TextureChannelMapping channel)
822{
823 if (m_roughnessChannel == channel)
824 return;
825 m_roughnessChannel = channel;
826 emit roughnessChannelChanged(channel);
827 markDirty(SpecularDirty);
828}
829
830void QQuick3DDefaultMaterial::setOpacityChannel(TextureChannelMapping channel)
831{
832 if (m_opacityChannel == channel)
833 return;
834 m_opacityChannel = channel;
835 emit opacityChannelChanged(channel);
836 markDirty(OpacityDirty);
837}
838
839void QQuick3DDefaultMaterial::setTranslucencyChannel(TextureChannelMapping channel)
840{
841 if (m_translucencyChannel == channel)
842 return;
843 m_translucencyChannel = channel;
844 emit translucencyChannelChanged(channel);
845 markDirty(TranslucencyDirty);
846}
847
848void QQuick3DDefaultMaterial::setPointSize(float size)
849{
850 if (qFuzzyCompare(m_pointSize, size))
851 return;
852 m_pointSize = size;
853 emit pointSizeChanged();
854 markDirty(PointSizeDirty);
855}
856
857void QQuick3DDefaultMaterial::setLineWidth(float width)
858{
859 if (qFuzzyCompare(m_lineWidth, width))
860 return;
861 m_lineWidth = width;
862 emit lineWidthChanged();
863 markDirty(LineWidthDirty);
864}
865
866QSSGRenderGraphObject *QQuick3DDefaultMaterial::updateSpatialNode(QSSGRenderGraphObject *node)
867{
868 if (!node) {
869 markAllDirty();
870 node = new QSSGRenderDefaultMaterial(QSSGRenderGraphObject::Type::DefaultMaterial);
871 }
872
873 static const auto channelMapping = [](TextureChannelMapping mapping) {
874 return QSSGRenderDefaultMaterial::TextureChannelMapping(mapping);
875 };
876
877 // Set common material properties
878 QQuick3DMaterial::updateSpatialNode(node);
879
880 QSSGRenderDefaultMaterial *material = static_cast<QSSGRenderDefaultMaterial *>(node);
881
882 if (m_dirtyAttributes & LightingModeDirty) {
883 material->lighting = QSSGRenderDefaultMaterial::MaterialLighting(m_lighting);
884 // If the lighthing mode changes it affects the emissive property
885 m_dirtyAttributes |= EmissiveDirty;
886 }
887
888 if (m_dirtyAttributes & BlendModeDirty)
889 material->blendMode = QSSGRenderDefaultMaterial::MaterialBlendMode(m_blendMode);
890
891 if (m_dirtyAttributes & DiffuseDirty) {
892 material->color = QSSGUtils::color::sRGBToLinear(m_diffuseColor);
893 if (!m_diffuseMap)
894 material->colorMap = nullptr;
895 else
896 material->colorMap = m_diffuseMap->getRenderImage();
897
898 material->diffuseLightWrap = m_diffuseLightWrap;
899 material->diffuseModel = QSSGRenderDefaultMaterial::MaterialDiffuseModel::Lambert;
900 }
901
902 if (m_dirtyAttributes & EmissiveDirty) {
903 if (!m_emissiveMap)
904 material->emissiveMap = nullptr;
905 else
906 material->emissiveMap = m_emissiveMap->getRenderImage();
907
908 material->emissiveColor = m_emissiveFactor;
909 }
910
911 if (m_dirtyAttributes & SpecularDirty) {
912 if (!m_specularReflectionMap)
913 material->specularReflection = nullptr;
914 else
915 material->specularReflection = m_specularReflectionMap->getRenderImage();
916
917 if (!m_specularMap)
918 material->specularMap = nullptr;
919 else
920 material->specularMap = m_specularMap->getRenderImage();
921
922 material->specularModel = QSSGRenderDefaultMaterial::MaterialSpecularModel(m_specularModel);
923 material->specularTint = QSSGUtils::color::sRGBToLinear(m_specularTint).toVector3D();
924 material->ior = m_indexOfRefraction;
925 material->fresnelPower = m_fresnelPower;
926 material->specularAmount = m_specularAmount;
927 material->specularRoughness = m_specularRoughness;
928 material->roughnessChannel = channelMapping(m_roughnessChannel);
929
930 if (!m_roughnessMap)
931 material->roughnessMap = nullptr;
932 else
933 material->roughnessMap = m_roughnessMap->getRenderImage();
934 }
935
936 if (m_dirtyAttributes & OpacityDirty) {
937 material->opacity = m_opacity;
938 material->opacityChannel = channelMapping(m_opacityChannel);
939 if (!m_opacityMap)
940 material->opacityMap = nullptr;
941 else
942 material->opacityMap = m_opacityMap->getRenderImage();
943 }
944
945 if (m_dirtyAttributes & BumpDirty) {
946 if (!m_bumpMap)
947 material->bumpMap = nullptr;
948 else
949 material->bumpMap = m_bumpMap->getRenderImage();
950 material->bumpAmount = m_bumpAmount;
951 }
952
953 if (m_dirtyAttributes & NormalDirty) {
954 if (!m_normalMap)
955 material->normalMap = nullptr;
956 else
957 material->normalMap = m_normalMap->getRenderImage();
958 }
959
960 if (m_dirtyAttributes & TranslucencyDirty) {
961 if (!m_translucencyMap)
962 material->translucencyMap = nullptr;
963 else
964 material->translucencyMap = m_translucencyMap->getRenderImage();
965 material->translucentFalloff = m_translucentFalloff;
966 material->translucencyChannel = channelMapping(m_translucencyChannel);
967 }
968
969 if (m_dirtyAttributes & VertexColorsDirty)
970 material->vertexColorsEnabled = m_vertexColorsEnabled;
971
972 if (m_dirtyAttributes & PointSizeDirty)
973 material->pointSize = m_pointSize;
974
975 if (m_dirtyAttributes & LineWidthDirty)
976 material->lineWidth = m_lineWidth;
977
978 m_dirtyAttributes = 0;
979
980 return node;
981}
982
983void QQuick3DDefaultMaterial::itemChange(QQuick3DObject::ItemChange change, const QQuick3DObject::ItemChangeData &value)
984{
985 if (change == QQuick3DObject::ItemSceneChange)
986 updateSceneManager(value.sceneManager);
987}
988
989void QQuick3DDefaultMaterial::updateSceneManager(QQuick3DSceneManager *sceneManager)
990{
991 // Check all the resource value's windows, and update as necessary
992 if (sceneManager) {
993 QQuick3DObjectPrivate::refSceneManager(m_diffuseMap, *sceneManager);
994 QQuick3DObjectPrivate::refSceneManager(m_emissiveMap, *sceneManager);
995 QQuick3DObjectPrivate::refSceneManager(m_specularReflectionMap, *sceneManager);
996 QQuick3DObjectPrivate::refSceneManager(m_specularMap, *sceneManager);
997 QQuick3DObjectPrivate::refSceneManager(m_roughnessMap, *sceneManager);
998 QQuick3DObjectPrivate::refSceneManager(m_opacityMap, *sceneManager);
999 QQuick3DObjectPrivate::refSceneManager(m_bumpMap, *sceneManager);
1000 QQuick3DObjectPrivate::refSceneManager(m_normalMap, *sceneManager);
1001 QQuick3DObjectPrivate::refSceneManager(m_translucencyMap, *sceneManager);
1002 } else {
1003 QQuick3DObjectPrivate::derefSceneManager(m_diffuseMap);
1004 QQuick3DObjectPrivate::derefSceneManager(m_emissiveMap);
1005 QQuick3DObjectPrivate::derefSceneManager(m_specularReflectionMap);
1006 QQuick3DObjectPrivate::derefSceneManager(m_specularMap);
1007 QQuick3DObjectPrivate::derefSceneManager(m_roughnessMap);
1008 QQuick3DObjectPrivate::derefSceneManager(m_opacityMap);
1009 QQuick3DObjectPrivate::derefSceneManager(m_bumpMap);
1010 QQuick3DObjectPrivate::derefSceneManager(m_normalMap);
1011 QQuick3DObjectPrivate::derefSceneManager(m_translucencyMap);
1012 }
1013}
1014
1015void QQuick3DDefaultMaterial::markDirty(QQuick3DDefaultMaterial::DirtyType type)
1016{
1017 if (!(m_dirtyAttributes & quint32(type))) {
1018 m_dirtyAttributes |= quint32(type);
1019 update();
1020 }
1021}
1022
1023QT_END_NAMESPACE
Combined button and popup list for selecting options.