1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qquick3dspecularglossymaterial_p.h"
5#include "qquick3dobject_p.h"
6
7#include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterial_p.h>
8#include <QtQuick3DUtils/private/qssgutils_p.h>
9#include <QtQuick3D/private/qquick3dviewport_p.h>
10
11QT_BEGIN_NAMESPACE
12
13/*!
14 \qmltype SpecularGlossyMaterial
15 \inherits Material
16 \inqmlmodule QtQuick3D
17 \brief Lets you define a material for 3D items using the specular/glossiness workflow.
18
19 Before a Model can be rendered in a scene, it must have at least one material attached
20 to it that describes how the mesh should be shaded. The SpecularGlossyMaterial is a PBR
21 specular/glossiness material that aims at being an easy to use material with a minimal
22 set of parameters.
23 In addition to having few parameters, all input values are strictly normalized
24 between 0 and 1 and have sensible defaults, meaning even without changing any values,
25 the material can be used to shader a model. For an introduction on how the
26 different properties of the SpecularGlossyMaterial affects how a model is shaded,
27 see the \l{Qt Quick 3D - Principled Material Example}{Principled Material example} which
28 provides a mode for using the Specular/Glossy workflow.
29
30 Alternatively to use the metallic/roughness workflow instead use \l {PrincipledMaterial}.
31
32 \section1 Specular/Glossiness workflow
33
34 The SpecularGlossyMaterial provides a way to create materials using a specular/glossiness
35 type workflow. The main properties of the material is controlled through
36 the \l {SpecularGlossyMaterial::specularMap} {specular},
37 \l {SpecularGlossyMaterial::glossinessMap} {glossiness},
38 and \l {SpecularGlossyMaterial::albedoMap} {albedo} properties.
39
40 \section2 Specular
41
42 The \l {SpecularGlossyMaterial::specularMap} {specularColor} property describes the specular
43 amount and color of an object's surface. For reflective materials the main color
44 contribution, comes from this property.
45
46 \section2 Glossiness
47
48 The \l {SpecularGlossyMaterial::glossinessMap} {glossiness} of a material describes the
49 condition of an object's surface. A high \c glossiness value means the object has a smooth
50 surface and therefore be more reflective then a material with a lower \c glossiness value.
51
52 \section2 Albedo
53
54 The \l {SpecularGlossyMaterial::albedoMap} {albedoColor} property describes the diffuse color
55 of the material, and unlike the \l {PrincipledMaterial}'s base color, the albedo
56 does not contain any information about the material reflectance. That means that for
57 reflective surfaces the albedo's color value should be set to a black tint, as that
58 will allow for the specular color to contribute.
59*/
60
61/*!
62 \qmlproperty enumeration SpecularGlossyMaterial::lighting
63
64 This property defines which lighting method is used when generating this
65 material.
66
67 The default value is \c SpecularGlossyMaterial.FragmentLighting
68
69 When using \c SpecularGlossyMaterial.FragmentLighting, diffuse and specular lighting is
70 calculated for each rendered pixel. Certain effects (such as a Fresnel or normal map) require
71 \c SpecularGlossyMaterial.FragmentLighting to work.
72
73 When using \c SpecularGlossyMaterial.NoLighting no lighting is calculated. This
74 mode is (predictably) very fast, and is quite effective when image maps are
75 used that you do not need to be shaded by lighting. All other shading
76 properties except albedo values, alpha values, and vertex colors will be
77 ignored.
78
79 \value SpecularGlossyMaterial.NoLighting
80 \value SpecularGlossyMaterial.FragmentLighting
81*/
82
83/*!
84 \qmlproperty enumeration SpecularGlossyMaterial::blendMode
85
86 This property determines how the colors of the model rendered blends with
87 those behind it.
88
89 \value SpecularGlossyMaterial.SourceOver Default blend mode. Opaque objects
90 occlude objects behind them. This default mode does not guarantee alpha
91 blending in the rendering pipeline on its own for models that use this
92 material, but rather makes the decision dependent on a number of factors:
93 if the object's and material's total opacity is \c{1.0}, there is no
94 opacity map in the material, and \l alphaMode is not set to a value that
95 enforces alpha blending, then the model is treated as opaque, meaning it is
96 rendered with depth testing and depth write enabled, together with other
97 opaque objects, with blending disabled. Otherwise the model is treated as
98 semi-transparent, and is rendered after the opaque objects, together with
99 other semi-transparent objects in a back-to-front order based on their
100 center's distance from the camera, with alpha blending enabled.
101
102 \value SpecularGlossyMaterial.Screen Colors are blended using an inverted
103 multiply, producing a lighter result. This blend mode is order-independent;
104 if you are using semi-opaque objects and experiencing 'popping' as faces or
105 models sort differently, using Screen blending is one way to produce
106 results without popping.
107
108 \value SpecularGlossyMaterial.Multiply Colors are blended using a multiply,
109 producing a darker result. This blend mode is also order-independent.
110
111 \sa alphaMode, {Qt Quick 3D Architecture}
112*/
113
114/*!
115 \qmlproperty color SpecularGlossyMaterial::albedoColor
116
117 This property sets the albedo color for the material. Setting the
118 diffuse color to a black tint will create a purely-specular material
119 (e.g. metals or mirrors).
120
121 \sa albedoMap, alphaMode
122*/
123
124/*!
125 \qmlproperty Texture SpecularGlossyMaterial::albedoMap
126
127 This property defines the texture used to set the albedo color of the material.
128
129 \sa albedo, alphaMode
130*/
131
132/*!
133 \qmlproperty color SpecularGlossyMaterial::specularColor
134
135 This property defines the specular RGB color. If an alpha value is provided it
136 will be ignored.
137
138 The default value is \c Qt.White
139*/
140
141/*!
142 \qmlproperty Texture SpecularGlossyMaterial::specularMap
143
144 This property sets a Texture to be used to set the specular color for the
145 different parts of the material. Only the RGB channels are used.
146*/
147
148/*!
149 \qmlproperty real SpecularGlossyMaterial::glossiness
150
151 This property controls the size of the specular highlight generated from
152 lights, and the clarity of reflections in general. Smaller values increase
153 the roughness, softening specular highlights and blurring reflections.
154 The range is [0.0, 1.0]. The default value is \c 1.0.
155*/
156
157/*!
158 \qmlproperty Texture SpecularGlossyMaterial::glossinessMap
159
160 This property defines a Texture to control the glossiness of the
161 material.
162*/
163
164/*!
165 \qmlproperty enumeration SpecularGlossyMaterial::glossinessChannel
166
167 This property defines the texture channel used to read the glossiness value
168 from glossinessMap.
169 The default value is \c Material.A.
170
171 \value Material.R Read value from texture R channel.
172 \value Material.G Read value from texture G channel.
173 \value Material.B Read value from texture B channel.
174 \value Material.A Read value from texture A channel.
175*/
176
177/*!
178 \qmlproperty Texture SpecularGlossyMaterial::emissiveMap
179
180 This property sets a RGB Texture to be used to specify the intensity of the
181 emissive color.
182*/
183
184/*!
185 \qmlproperty vector3d SpecularGlossyMaterial::emissiveFactor
186
187 This property determines the color of self-illumination for this material.
188 If an emissive map is set, the x, y, and z components are used as factors
189 (multipliers) for the R, G and B channels of the texture, respectively.
190 The default value is (0, 0, 0) and it means no emissive contribution at all.
191
192 \note Setting the lightingMode to DefaultMaterial.NoLighting means emissive
193 Factor does not have an effect on the scene.
194*/
195
196/*!
197 \qmlproperty real SpecularGlossyMaterial::opacity
198
199 This property drops the opacity of just this material, separate from the
200 model.
201*/
202
203/*!
204 \qmlproperty Texture SpecularGlossyMaterial::opacityMap
205
206 This property defines a Texture used to control the opacity differently for
207 different parts of the material.
208*/
209
210/*!
211 \qmlproperty enumeration SpecularGlossyMaterial::opacityChannel
212
213 This property defines the texture channel used to read the opacity value from opacityMap.
214 The default value is \c Material.A.
215
216 \value Material.R Read value from texture R channel.
217 \value Material.G Read value from texture G channel.
218 \value Material.B Read value from texture B channel.
219 \value Material.A Read value from texture A channel.
220*/
221
222/*!
223 \qmlproperty Texture SpecularGlossyMaterial::normalMap
224
225 This property defines an RGB image used to simulate fine geometry
226 displacement across the surface of the material. The RGB channels indicate
227 XYZ normal deviations.
228
229 \note Normal maps will not affect the silhouette of a model.
230*/
231
232/*!
233 \qmlproperty real SpecularGlossyMaterial::normalStrength
234
235 This property controls the amount of simulated displacement for the normalMap.
236*/
237
238/*!
239 \qmlproperty real SpecularGlossyMaterial::occlusionAmount
240
241 This property contains the factor used to modify the values from the \l occlusionMap texture.
242 The value should be between 0.0 to 1.0. The default is 1.0
243*/
244
245/*!
246 \qmlproperty Texture SpecularGlossyMaterial::occlusionMap
247
248 This property defines a texture used to determine how much indirect light the different areas of the
249 material should receive. Values are expected to be linear from 0.0 to 1.0, where 0.0 means no indirect lighting
250 and 1.0 means the effect of the indirect lighting is left unchanged.
251
252 \sa occlusionAmount
253*/
254
255/*!
256 \qmlproperty enumeration SpecularGlossyMaterial::occlusionChannel
257
258 This property defines the texture channel used to read the occlusion value from occlusionMap.
259 The default value is \c Material.R.
260
261 \value Material.R Read value from texture R channel.
262 \value Material.G Read value from texture G channel.
263 \value Material.B Read value from texture B channel.
264 \value Material.A Read value from texture A channel.
265*/
266
267/*!
268 \qmlproperty enumeration SpecularGlossyMaterial::alphaMode
269
270 This property specifies how the alpha color value from \l albedoColor and the
271 alpha channel of a \l{albedoMap}{albedo map} are used.
272
273 \note The alpha cutoff test only considers the albedo color alpha. \l opacity
274 and \l [QtQuick3D] {Node::opacity} are not taken into account there.
275
276 \note When sampling an albedo color map, the effective alpha value is the
277 sampled alpha multiplied by the \l albedoColor alpha.
278
279 \value SpecularGlossyMaterial.Default No test is applied, the effective alpha
280 value is passed on as-is. Note that a \l albedoColor or \l albedoMap alpha
281 less than \c 1.0 does not automatically imply alpha blending, the object
282 with the material may still be treated as opaque, if no other relevant
283 properties (such as, an opacity less than 1, the presence of an opacity
284 map, or a non-default \l blendMode value) trigger treating the object as
285 semi-transparent. To ensure alpha blending happens regardless of any other
286 object or material property, set \c Blend instead.
287
288 \value SpecularGlossyMaterial.Blend No cutoff test is applied, but guarantees
289 that alpha blending happens. The object with this material will therefore
290 never be treated as opaque by the renderer.
291
292 \value SpecularGlossyMaterial.Opaque No cutoff test is applied and the rendered
293 object is assumed to be fully opaque, meaning the alpha values in the
294 vertex color, albedo color, and albedo color map are ignored and a value of 1.0
295 is substituted instead. This mode does not guarantee alpha blending does
296 not happen. If relevant properties (such as, an opacity less than 1, an
297 opacity map, or a non-default \l blendMode) say so, then the object will
298 still be treated as semi-transparent by the rendering pipeline, just like
299 with the \c Default alphaMode.
300
301 \value SpecularGlossyMaterial.Mask A test based on \l alphaCutoff is applied.
302 If the effective alpha value falls below \l alphaCutoff, the fragment is
303 changed to fully transparent and is discarded (with all implications of
304 discarding: the depth buffer is not written for that fragment). Otherwise
305 the alpha is changed to 1.0, so that the fragment will become fully opaque.
306 When it comes to alpha blending, the behavior of this mode is identical to
307 \c Opaque, regardless of the cutoff test's result. This means that the
308 \l{https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#alpha-coverage}{glTF
309 2 spec's alpha coverage} Implementation Notes are fulfilled. Objects with
310 alpha cutoff tests can also cast shadows since they behave like opaque
311 objects by default, unless the relevant properties (such as, an opacity
312 less than 1, an opacity map, or a non-default \l blendMode) imply otherwise
313 (in which case casting shadows will not be possible).
314
315 \sa alphaCutoff, blendMode
316*/
317
318/*!
319 \qmlproperty real SpecularGlossyMaterial::alphaCutoff
320
321 The alphaCutoff property can be used to specify the cutoff value when using
322 the \l{alphaMode}{Mask alphaMode}. Fragments where the alpha value falls
323 below the threshold will be rendered fully transparent (\c{0.0} for all
324 color channels). When the alpha value is equal or greater than the cutoff
325 value, the color will not be affected in any way.
326
327 The default value is 0.5.
328
329 \sa alphaMode
330*/
331
332/*!
333 \qmlproperty real SpecularGlossyMaterial::pointSize
334
335 This property determines the size of the points rendered, when the geometry
336 is using a primitive type of points. The default value is 1.0. This
337 property is not relevant when rendering other types of geometry, such as,
338 triangle meshes.
339
340 \warning Point sizes other than 1 may not be supported at run time,
341 depending on the underyling graphics API. For example, setting a size other
342 than 1 has no effect with Direct 3D.
343*/
344
345/*!
346 \qmlproperty real SpecularGlossyMaterial::lineWidth
347
348 This property determines the width of the lines rendered, when the geometry
349 is using a primitive type of lines or line strips. The default value is
350 1.0. This property is not relevant when rendering other types of geometry,
351 such as, triangle meshes.
352
353 \warning Line widths other than 1 may not be suported at run time,
354 depending on the underlying graphics API. When that is the case, the
355 request to change the width is ignored. For example, none of the following
356 can be expected to support wide lines: Direct3D, Metal, OpenGL with core
357 profile contexts.
358*/
359
360/*!
361 \qmlproperty Texture SpecularGlossyMaterial::heightMap
362
363 This property defines a texture used to determine the height the texture
364 will be displaced when rendered through the use of Parallax Mapping. Values
365 are expected to be linear from 0.0 to 1.0, where 0.0 means no displacement
366 and 1.0 means means maximum displacement.
367
368*/
369
370/*!
371 \qmlproperty enumeration SpecularGlossyMaterial::heightChannel
372
373 This property defines the texture channel used to read the height value
374 from heightMap. The default value is \c Material.R.
375
376 \value Material.R Read value from texture R channel.
377 \value Material.G Read value from texture G channel.
378 \value Material.B Read value from texture B channel.
379 \value Material.A Read value from texture A channel.
380
381*/
382
383/*!
384 \qmlproperty real SpecularGlossyMaterial::heightAmount
385
386 This property contains the factor used to modify the values from the
387 \l heightMap texture. The value should be between 0.0 to 1.0. The default
388 value is 0.0 which means that height displacement will be disabled, even
389 if a height map set.
390*/
391
392/*!
393 \qmlproperty int SpecularGlossyMaterial::minHeightMapSamples
394
395 This property defines the minimum number of samples used for performing
396 Parallex Occlusion Mapping using the \l heightMap. The minHeightMapSamples
397 value is the number of samples of the heightMap are used when looking directly
398 at a surface (when the camera view is perpendicular to the fragment).
399 The default value is 8.
400
401 The actual number of samples used for each fragment will be between
402 \l minHeightMapSamples and \l maxHeightMapSamples depending on the angle of
403 the camera relative to the surface being rendered.
404
405 \note This value should only be adjusted to fine tune materials using a
406 \l heightMap in the case undesired artifacts are present.
407*/
408
409/*!
410 \qmlproperty int SpecularGlossyMaterial::maxHeightMapSamples
411
412 This property defines the maximum number of samples used for performing
413 Parallex Occlusion Mapping using the \l heightMap. The maxHeightMapSamples
414 value is the number of samples of the heightMap are used when looking
415 parallel to a surface.
416 The default value is 32.
417
418 The actual number of samples used for each fragment will be between
419 \l minHeightMapSamples and \l maxHeightMapSamples depending on the angle of
420 the camera relative to the surface being rendered.
421
422 \note This value should only be adjusted to fine tune materials using a
423 \l heightMap in the case undesired artifacts are present.
424*/
425
426/*!
427 \qmlproperty float SpecularGlossyMaterial::clearcoatAmount
428
429 This property defines the intensity of the clearcoat layer.
430
431 The default value is \c 0.0
432*/
433
434/*!
435 \qmlproperty Texture SpecularGlossyMaterial::clearcoatMap
436
437 This property defines a texture used to determine the intensity of the
438 clearcoat layer. The value of\l clearcoatAmount will be multiplied by
439 the value read from this texture.
440
441*/
442
443/*!
444 \qmlproperty enumeration SpecularGlossyMaterial::clearcoatChannel
445
446 This property defines the texture channel used to read the clearcoat amount
447 value from \l clearcoatMap. The default value is \c Material.R.
448
449 \value Material.R Read value from texture R channel.
450 \value Material.G Read value from texture G channel.
451 \value Material.B Read value from texture B channel.
452 \value Material.A Read value from texture A channel.
453
454*/
455
456/*!
457 \qmlproperty float SpecularGlossyMaterial::clearcoatRoughnessAmount
458
459 This property defines the roughness of the clearcoat layer.
460 The default value is \c 0.0
461*/
462
463/*!
464 \qmlproperty Texture SpecularGlossyMaterial::clearcoatRoughnessMap
465
466 This property defines a texture used to determine the roughness of the
467 clearcoat layer. The value of\l clearcoatRoughnessAmount will be
468 multiplied by the value read from this texture.
469
470*/
471
472/*!
473 \qmlproperty enumeration SpecularGlossyMaterial::clearcoatRoughnessChannel
474
475 This property defines the texture channel used to read the clearcoat
476 roughness amount from \l clearcoatRoughnessMap.
477 The default value is \c Material.G.
478
479 \value Material.R Read value from texture R channel.
480 \value Material.G Read value from texture G channel.
481 \value Material.B Read value from texture B channel.
482 \value Material.A Read value from texture A channel.
483
484*/
485
486/*!
487 \qmlproperty Texture SpecularGlossyMaterial::clearcoatNormalMap
488
489 This property defines a texture used to determine the normal mapping
490 applied to the clearcoat layer.
491
492*/
493
494/*!
495 \qmlproperty float SpecularGlossyMaterial::transmissionFactor
496
497 This property defines the percentage of light that is transmitted through
498 the material's surface.
499 The default value is \c 0.0
500*/
501
502/*!
503 \qmlproperty Texture SpecularGlossyMaterial::transmissionMap
504
505 This property defines a texture used to determine percentage of light that
506 is transmitted through the surface.. The value of
507 \l transmissionFactor will be multiplied by the value read from this
508 texture.
509
510*/
511
512/*!
513 \qmlproperty enumeration SpecularGlossyMaterial::transmissionChannel
514
515 This property defines the texture channel used to read the transmission
516 percentage from \l transmissionMap.
517 The default value is \c Material.R.
518
519 \value Material.R Read value from texture R channel.
520 \value Material.G Read value from texture G channel.
521 \value Material.B Read value from texture B channel.
522 \value Material.A Read value from texture A channel.
523
524*/
525
526/*!
527 \qmlproperty float SpecularGlossyMaterial::thicknessFactor
528
529 This property defines the thickness of the volume beneath the surface.
530 Unlike many other properties of SpecularGlossyMaterial, the value in defined
531 in thicknessFactor is a value from 0.0 to +infinity for thickness in the
532 models coordinate space. A value of 0.0 means that the material is
533 thin-walled.
534 The default value is \c 0.0
535*/
536
537/*!
538 \qmlproperty Texture SpecularGlossyMaterial::thicknessMap
539
540 This property defines a texture used to define the thickness of a
541 material volume. The value of \l thicknessFactor will be multiplied by the
542 value read from this texture.
543
544*/
545
546/*!
547 \qmlproperty enumeration SpecularGlossyMaterial::thicknessChannel
548
549 This property defines the texture channel used to read the thickness
550 amount from \l transmissionMap.
551 The default value is \c Material.G.
552
553 \value Material.R Read value from texture R channel.
554 \value Material.G Read value from texture G channel.
555 \value Material.B Read value from texture B channel.
556 \value Material.A Read value from texture A channel.
557
558*/
559
560/*!
561 \qmlproperty float SpecularGlossyMaterial::attenuationDistance
562
563 This property defines the Density of the medium given as the average
564 distance that light travels in the medium before interacting with a
565 particle. The value is given in world space.
566 The default value is \c +infinity.
567*/
568
569/*!
570 \qmlproperty color SpecularGlossyMaterial::attenuationColor
571
572 This property defines the color that white lights turns into due to
573 absorption when reaching the attenuation distance.
574 The default value is \c Qt.White
575
576*/
577
578/*!
579 \qmlproperty bool SpecularGlossyMaterial::vertexColorsEnabled
580 \since 6.5
581
582 When this property is enabled, the material will use vertex colors from the
583 mesh. These will be multiplied by any other colors specified for the
584 material. The default value is true.
585*/
586
587inline static float ensureNormalized(float val) { return qBound(min: 0.0f, val, max: 1.0f); }
588
589QQuick3DSpecularGlossyMaterial::QQuick3DSpecularGlossyMaterial(QQuick3DObject *parent)
590 : QQuick3DMaterial(*(new QQuick3DObjectPrivate(QQuick3DObjectPrivate::Type::SpecularGlossyMaterial)), parent)
591{}
592
593QQuick3DSpecularGlossyMaterial::~QQuick3DSpecularGlossyMaterial()
594{
595}
596
597QQuick3DSpecularGlossyMaterial::Lighting QQuick3DSpecularGlossyMaterial::lighting() const
598{
599 return m_lighting;
600}
601
602QQuick3DSpecularGlossyMaterial::BlendMode QQuick3DSpecularGlossyMaterial::blendMode() const
603{
604 return m_blendMode;
605}
606
607QColor QQuick3DSpecularGlossyMaterial::albedoColor() const
608{
609 return m_albedo;
610}
611
612QQuick3DTexture *QQuick3DSpecularGlossyMaterial::albedoMap() const
613{
614 return m_albedoMap;
615}
616
617QQuick3DTexture *QQuick3DSpecularGlossyMaterial::emissiveMap() const
618{
619 return m_emissiveMap;
620}
621
622QVector3D QQuick3DSpecularGlossyMaterial::emissiveFactor() const
623{
624 return m_emissiveFactor;
625}
626
627float QQuick3DSpecularGlossyMaterial::glossiness() const
628{
629 return m_glossiness;
630}
631
632QQuick3DTexture *QQuick3DSpecularGlossyMaterial::glossinessMap() const
633{
634 return m_glossinessMap;
635}
636
637float QQuick3DSpecularGlossyMaterial::opacity() const
638{
639 return m_opacity;
640}
641
642QQuick3DTexture *QQuick3DSpecularGlossyMaterial::opacityMap() const
643{
644 return m_opacityMap;
645}
646
647QQuick3DTexture *QQuick3DSpecularGlossyMaterial::normalMap() const
648{
649 return m_normalMap;
650}
651
652QColor QQuick3DSpecularGlossyMaterial::specularColor() const
653{
654 return m_specular;
655}
656
657QQuick3DTexture *QQuick3DSpecularGlossyMaterial::specularMap() const
658{
659 return m_specularMap;
660}
661
662float QQuick3DSpecularGlossyMaterial::normalStrength() const
663{
664 return m_normalStrength;
665}
666
667QQuick3DTexture *QQuick3DSpecularGlossyMaterial::occlusionMap() const
668{
669 return m_occlusionMap;
670}
671
672float QQuick3DSpecularGlossyMaterial::occlusionAmount() const
673{
674 return m_occlusionAmount;
675}
676
677QQuick3DSpecularGlossyMaterial::AlphaMode QQuick3DSpecularGlossyMaterial::alphaMode() const
678{
679 return m_alphaMode;
680}
681
682float QQuick3DSpecularGlossyMaterial::alphaCutoff() const
683{
684 return m_alphaCutoff;
685}
686
687QQuick3DMaterial::TextureChannelMapping QQuick3DSpecularGlossyMaterial::glossinessChannel() const
688{
689 return m_glossinessChannel;
690}
691
692QQuick3DMaterial::TextureChannelMapping QQuick3DSpecularGlossyMaterial::opacityChannel() const
693{
694 return m_opacityChannel;
695}
696
697QQuick3DMaterial::TextureChannelMapping QQuick3DSpecularGlossyMaterial::occlusionChannel() const
698{
699 return m_occlusionChannel;
700}
701
702float QQuick3DSpecularGlossyMaterial::pointSize() const
703{
704 return m_pointSize;
705}
706
707float QQuick3DSpecularGlossyMaterial::lineWidth() const
708{
709 return m_lineWidth;
710}
711
712QQuick3DTexture *QQuick3DSpecularGlossyMaterial::heightMap() const
713{
714 return m_heightMap;
715}
716
717QQuick3DMaterial::TextureChannelMapping QQuick3DSpecularGlossyMaterial::heightChannel() const
718{
719 return m_heightChannel;
720}
721
722float QQuick3DSpecularGlossyMaterial::heightAmount() const
723{
724 return m_heightAmount;
725}
726
727int QQuick3DSpecularGlossyMaterial::minHeightMapSamples() const
728{
729 return m_minHeightMapSamples;
730}
731
732int QQuick3DSpecularGlossyMaterial::maxHeightMapSamples() const
733{
734 return m_maxHeightMapSamples;
735}
736
737void QQuick3DSpecularGlossyMaterial::markAllDirty()
738{
739 m_dirtyAttributes = 0xffffffff;
740 QQuick3DMaterial::markAllDirty();
741}
742
743void QQuick3DSpecularGlossyMaterial::setLighting(QQuick3DSpecularGlossyMaterial::Lighting lighting)
744{
745 if (m_lighting == lighting)
746 return;
747
748 m_lighting = lighting;
749 emit lightingChanged();
750 markDirty(type: LightingModeDirty);
751}
752
753void QQuick3DSpecularGlossyMaterial::setBlendMode(QQuick3DSpecularGlossyMaterial::BlendMode blendMode)
754{
755 if (m_blendMode == blendMode)
756 return;
757
758 m_blendMode = blendMode;
759 emit blendModeChanged();
760 markDirty(type: BlendModeDirty);
761}
762
763void QQuick3DSpecularGlossyMaterial::setAlbedoColor(const QColor &diffuseColor)
764{
765 if (m_albedo == diffuseColor)
766 return;
767
768 m_albedo = diffuseColor;
769 emit albedoColorChanged();
770 markDirty(type: AlbedoDirty);
771}
772
773void QQuick3DSpecularGlossyMaterial::setAlbedoMap(QQuick3DTexture *albedoMap)
774{
775 if (m_albedoMap == albedoMap)
776 return;
777
778 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSpecularGlossyMaterial::setAlbedoMap, newO: albedoMap, oldO: m_albedoMap);
779
780 m_albedoMap = albedoMap;
781 emit albedoMapChanged();
782 markDirty(type: AlbedoDirty);
783}
784
785void QQuick3DSpecularGlossyMaterial::setEmissiveMap(QQuick3DTexture *emissiveMap)
786{
787 if (m_emissiveMap == emissiveMap)
788 return;
789
790 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSpecularGlossyMaterial::setEmissiveMap, newO: emissiveMap, oldO: m_emissiveMap);
791
792 m_emissiveMap = emissiveMap;
793 emit emissiveMapChanged();
794 markDirty(type: EmissiveDirty);
795}
796
797void QQuick3DSpecularGlossyMaterial::setEmissiveFactor(const QVector3D &emissiveFactor)
798{
799 if (m_emissiveFactor == emissiveFactor)
800 return;
801
802 m_emissiveFactor = emissiveFactor;
803 emit emissiveFactorChanged();
804 markDirty(type: EmissiveDirty);
805}
806
807void QQuick3DSpecularGlossyMaterial::setGlossiness(float glossiness)
808{
809 glossiness = ensureNormalized(val: glossiness);
810 if (qFuzzyCompare(p1: m_glossiness, p2: glossiness))
811 return;
812
813 m_glossiness = glossiness;
814 emit glossinessChanged();
815 markDirty(type: GlossyDirty);
816}
817
818void QQuick3DSpecularGlossyMaterial::setGlossinessMap(QQuick3DTexture *glossinessMap)
819{
820 if (m_glossinessMap == glossinessMap)
821 return;
822
823 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSpecularGlossyMaterial::setGlossinessMap, newO: glossinessMap, oldO: m_glossinessMap);
824
825 m_glossinessMap = glossinessMap;
826 emit glossinessMapChanged();
827 markDirty(type: GlossyDirty);
828}
829
830void QQuick3DSpecularGlossyMaterial::setOpacity(float opacity)
831{
832 opacity = ensureNormalized(val: opacity);
833 if (qFuzzyCompare(p1: m_opacity, p2: opacity))
834 return;
835
836 m_opacity = opacity;
837 emit opacityChanged();
838 markDirty(type: OpacityDirty);
839}
840
841void QQuick3DSpecularGlossyMaterial::setOpacityMap(QQuick3DTexture *opacityMap)
842{
843 if (m_opacityMap == opacityMap)
844 return;
845
846 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSpecularGlossyMaterial::setOpacityMap, newO: opacityMap, oldO: m_opacityMap);
847
848 m_opacityMap = opacityMap;
849 emit opacityMapChanged();
850 markDirty(type: OpacityDirty);
851}
852
853void QQuick3DSpecularGlossyMaterial::setNormalMap(QQuick3DTexture *normalMap)
854{
855 if (m_normalMap == normalMap)
856 return;
857
858 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSpecularGlossyMaterial::setNormalMap, newO: normalMap, oldO: m_normalMap);
859
860 m_normalMap = normalMap;
861 emit normalMapChanged();
862 markDirty(type: NormalDirty);
863}
864
865void QQuick3DSpecularGlossyMaterial::setSpecularColor(const QColor &specular)
866{
867 if (m_specular == specular)
868 return;
869
870 m_specular = specular;
871 emit specularColorChanged();
872 markDirty(type: SpecularDirty);
873}
874
875void QQuick3DSpecularGlossyMaterial::setSpecularMap(QQuick3DTexture *specularMap)
876{
877 if (m_specularMap == specularMap)
878 return;
879
880 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSpecularGlossyMaterial::setSpecularMap, newO: specularMap, oldO: m_specularMap);
881
882 m_specularMap = specularMap;
883 emit specularMapChanged();
884 markDirty(type: SpecularDirty);
885}
886
887void QQuick3DSpecularGlossyMaterial::setNormalStrength(float factor)
888{
889 factor = ensureNormalized(val: factor);
890 if (qFuzzyCompare(p1: m_normalStrength, p2: factor))
891 return;
892
893 m_normalStrength = factor;
894 emit normalStrengthChanged();
895 markDirty(type: NormalDirty);
896}
897
898void QQuick3DSpecularGlossyMaterial::setOcclusionMap(QQuick3DTexture *occlusionMap)
899{
900 if (m_occlusionMap == occlusionMap)
901 return;
902
903 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSpecularGlossyMaterial::setOcclusionMap, newO: occlusionMap, oldO: m_occlusionMap);
904
905 m_occlusionMap = occlusionMap;
906 emit occlusionMapChanged();
907 markDirty(type: OcclusionDirty);
908}
909
910void QQuick3DSpecularGlossyMaterial::setOcclusionAmount(float occlusionAmount)
911{
912 if (qFuzzyCompare(p1: m_occlusionAmount, p2: occlusionAmount))
913 return;
914
915 m_occlusionAmount = occlusionAmount;
916 emit occlusionAmountChanged();
917 markDirty(type: OcclusionDirty);
918}
919
920void QQuick3DSpecularGlossyMaterial::setAlphaMode(QQuick3DSpecularGlossyMaterial::AlphaMode alphaMode)
921{
922 if (m_alphaMode == alphaMode)
923 return;
924
925 m_alphaMode = alphaMode;
926 emit alphaModeChanged();
927 markDirty(type: AlphaModeDirty);
928}
929
930void QQuick3DSpecularGlossyMaterial::setAlphaCutoff(float alphaCutoff)
931{
932 if (qFuzzyCompare(p1: m_alphaCutoff, p2: alphaCutoff))
933 return;
934
935 m_alphaCutoff = alphaCutoff;
936 emit alphaCutoffChanged();
937 markDirty(type: AlphaModeDirty);
938}
939
940void QQuick3DSpecularGlossyMaterial::setGlossinessChannel(TextureChannelMapping channel)
941{
942 if (m_glossinessChannel == channel)
943 return;
944
945 m_glossinessChannel = channel;
946 emit glossinessChannelChanged();
947 markDirty(type: GlossyDirty);
948}
949
950void QQuick3DSpecularGlossyMaterial::setOpacityChannel(TextureChannelMapping channel)
951{
952 if (m_opacityChannel == channel)
953 return;
954
955 m_opacityChannel = channel;
956 emit opacityChannelChanged();
957 markDirty(type: OpacityDirty);
958}
959
960void QQuick3DSpecularGlossyMaterial::setOcclusionChannel(TextureChannelMapping channel)
961{
962 if (m_occlusionChannel == channel)
963 return;
964
965 m_occlusionChannel = channel;
966 emit occlusionChannelChanged();
967 markDirty(type: OcclusionDirty);
968}
969
970void QQuick3DSpecularGlossyMaterial::setPointSize(float size)
971{
972 if (qFuzzyCompare(p1: m_pointSize, p2: size))
973 return;
974 m_pointSize = size;
975 emit pointSizeChanged();
976 markDirty(type: PointSizeDirty);
977}
978
979void QQuick3DSpecularGlossyMaterial::setLineWidth(float width)
980{
981 if (qFuzzyCompare(p1: m_lineWidth, p2: width))
982 return;
983 m_lineWidth = width;
984 emit lineWidthChanged();
985 markDirty(type: LineWidthDirty);
986}
987
988void QQuick3DSpecularGlossyMaterial::setHeightMap(QQuick3DTexture *heightMap)
989{
990 if (m_heightMap == heightMap)
991 return;
992
993 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSpecularGlossyMaterial::setHeightMap, newO: heightMap, oldO: m_heightMap);
994
995 m_heightMap = heightMap;
996 emit heightMapChanged();
997 markDirty(type: HeightDirty);
998}
999
1000void QQuick3DSpecularGlossyMaterial::setHeightChannel(QQuick3DMaterial::TextureChannelMapping channel)
1001{
1002 if (m_heightChannel == channel)
1003 return;
1004
1005 m_heightChannel = channel;
1006 emit heightChannelChanged();
1007 markDirty(type: HeightDirty);
1008}
1009
1010void QQuick3DSpecularGlossyMaterial::setHeightAmount(float heightAmount)
1011{
1012 if (qFuzzyCompare(p1: m_heightAmount, p2: heightAmount))
1013 return;
1014
1015 m_heightAmount = heightAmount;
1016 emit heightAmountChanged();
1017 markDirty(type: HeightDirty);
1018}
1019
1020void QQuick3DSpecularGlossyMaterial::setMinHeightMapSamples(int samples)
1021{
1022 if (m_minHeightMapSamples == samples)
1023 return;
1024
1025 m_minHeightMapSamples = samples;
1026 emit minHeightMapSamplesChanged();
1027 markDirty(type: HeightDirty);
1028}
1029
1030void QQuick3DSpecularGlossyMaterial::setMaxHeightMapSamples(int samples)
1031{
1032 if (m_maxHeightMapSamples == samples)
1033 return;
1034
1035 m_maxHeightMapSamples = samples;
1036 emit maxHeightMapSamplesChanged();
1037 markDirty(type: HeightDirty);
1038}
1039
1040QSSGRenderGraphObject *QQuick3DSpecularGlossyMaterial::updateSpatialNode(QSSGRenderGraphObject *node)
1041{
1042 static const auto channelMapping = [](TextureChannelMapping mapping) {
1043 return QSSGRenderDefaultMaterial::TextureChannelMapping(mapping);
1044 };
1045
1046 if (!node) {
1047 markAllDirty();
1048 node = new QSSGRenderDefaultMaterial(QSSGRenderGraphObject::Type::SpecularGlossyMaterial);
1049 }
1050
1051 // Set common material properties
1052 QQuick3DMaterial::updateSpatialNode(node);
1053
1054 QSSGRenderDefaultMaterial *material = static_cast<QSSGRenderDefaultMaterial *>(node);
1055
1056 material->specularModel = QSSGRenderDefaultMaterial::MaterialSpecularModel::KGGX;
1057
1058 if (m_dirtyAttributes & LightingModeDirty)
1059 material->lighting = QSSGRenderDefaultMaterial::MaterialLighting(m_lighting);
1060
1061 if (m_dirtyAttributes & BlendModeDirty)
1062 material->blendMode = QSSGRenderDefaultMaterial::MaterialBlendMode(m_blendMode);
1063
1064 if (m_dirtyAttributes & AlbedoDirty) {
1065 if (!m_albedoMap)
1066 material->colorMap = nullptr;
1067 else
1068 material->colorMap = m_albedoMap->getRenderImage();
1069
1070 material->color = QSSGUtils::color::sRGBToLinear(color: m_albedo);
1071 }
1072
1073 if (m_dirtyAttributes & EmissiveDirty) {
1074 if (!m_emissiveMap)
1075 material->emissiveMap = nullptr;
1076 else
1077 material->emissiveMap = m_emissiveMap->getRenderImage();
1078
1079 material->emissiveColor = m_emissiveFactor;
1080 }
1081
1082 material->fresnelPower = 5.0f;
1083 material->vertexColorsEnabled = false;
1084
1085 if (m_dirtyAttributes & GlossyDirty) {
1086 if (!m_glossinessMap)
1087 material->roughnessMap = nullptr;
1088 else
1089 material->roughnessMap = m_glossinessMap->getRenderImage();
1090
1091 material->specularRoughness = m_glossiness;
1092 material->roughnessChannel = channelMapping(m_glossinessChannel);
1093 }
1094
1095 if (m_dirtyAttributes & SpecularDirty) {
1096 if (!m_specularMap)
1097 material->specularMap = nullptr;
1098 else
1099 material->specularMap = m_specularMap->getRenderImage();
1100
1101 material->specularTint = QSSGUtils::color::sRGBToLinear(color: m_specular).toVector3D();
1102 }
1103
1104 if (m_dirtyAttributes & OpacityDirty) {
1105 if (!m_opacityMap)
1106 material->opacityMap = nullptr;
1107 else
1108 material->opacityMap = m_opacityMap->getRenderImage();
1109
1110 material->opacity = m_opacity;
1111 material->opacityChannel = channelMapping(m_opacityChannel);
1112 }
1113
1114 if (m_dirtyAttributes & NormalDirty) {
1115 if (!m_normalMap)
1116 material->normalMap = nullptr;
1117 else
1118 material->normalMap = m_normalMap->getRenderImage();
1119
1120 material->bumpAmount = m_normalStrength;
1121 }
1122
1123 if (m_dirtyAttributes & OcclusionDirty) {
1124 if (!m_occlusionMap)
1125 material->occlusionMap = nullptr;
1126 else
1127 material->occlusionMap = m_occlusionMap->getRenderImage();
1128 material->occlusionAmount = m_occlusionAmount;
1129 material->occlusionChannel = channelMapping(m_occlusionChannel);
1130 }
1131
1132 if (m_dirtyAttributes & AlphaModeDirty) {
1133 material->alphaMode = QSSGRenderDefaultMaterial::MaterialAlphaMode(m_alphaMode);
1134 material->alphaCutoff = m_alphaCutoff;
1135 }
1136
1137 if (m_dirtyAttributes & PointSizeDirty)
1138 material->pointSize = m_pointSize;
1139
1140 if (m_dirtyAttributes & LineWidthDirty)
1141 material->lineWidth = m_lineWidth;
1142
1143 if (m_dirtyAttributes & HeightDirty) {
1144 if (!m_heightMap)
1145 material->heightMap = nullptr;
1146 else
1147 material->heightMap = m_heightMap->getRenderImage();
1148 material->heightAmount = m_heightAmount;
1149 material->minHeightSamples = m_minHeightMapSamples;
1150 material->maxHeightSamples = m_maxHeightMapSamples;
1151 material->heightChannel = channelMapping(m_heightChannel);
1152 }
1153
1154 if (m_dirtyAttributes & ClearcoatDirty) {
1155 material->clearcoatAmount = m_clearcoatAmount;
1156 if (!m_clearcoatMap)
1157 material->clearcoatMap = nullptr;
1158 else
1159 material->clearcoatMap = m_clearcoatMap->getRenderImage();
1160 material->clearcoatChannel = channelMapping(m_clearcoatChannel);
1161 material->clearcoatRoughnessAmount = m_clearcoatRoughnessAmount;
1162 if (!m_clearcoatRoughnessMap)
1163 material->clearcoatRoughnessMap = nullptr;
1164 else
1165 material->clearcoatRoughnessMap = m_clearcoatRoughnessMap->getRenderImage();
1166 material->clearcoatRoughnessChannel = channelMapping(m_clearcoatRoughnessChannel);
1167 if (!m_clearcoatNormalMap)
1168 material->clearcoatNormalMap = nullptr;
1169 else
1170 material->clearcoatNormalMap = m_clearcoatNormalMap->getRenderImage();
1171 }
1172
1173 if (m_dirtyAttributes & TransmissionDirty) {
1174 material->transmissionFactor = m_transmissionFactor;
1175 if (!m_transmissionMap)
1176 material->transmissionMap = nullptr;
1177 else
1178 material->transmissionMap = m_transmissionMap->getRenderImage();
1179 material->transmissionChannel = channelMapping(m_transmissionChannel);
1180 }
1181
1182 if (m_dirtyAttributes & VolumeDirty) {
1183 material->thicknessFactor = m_thicknessFactor;
1184 if (!m_thicknessMap)
1185 material->thicknessMap = nullptr;
1186 else
1187 material->thicknessMap = m_thicknessMap->getRenderImage();
1188 material->thicknessChannel = channelMapping(m_thicknessChannel);
1189
1190 material->attenuationDistance = m_attenuationDistance;
1191 material->attenuationColor = QSSGUtils::color::sRGBToLinear(color: m_attenuationColor).toVector3D();
1192 }
1193
1194 if (m_dirtyAttributes & VertexColorsDirty)
1195 material->vertexColorsEnabled = m_vertexColorsEnabled;
1196
1197 m_dirtyAttributes = 0;
1198
1199 return node;
1200}
1201
1202void QQuick3DSpecularGlossyMaterial::itemChange(QQuick3DObject::ItemChange change, const QQuick3DObject::ItemChangeData &value)
1203{
1204 if (change == QQuick3DObject::ItemSceneChange)
1205 updateSceneManager(window: value.sceneManager);
1206}
1207
1208void QQuick3DSpecularGlossyMaterial::updateSceneManager(QQuick3DSceneManager *sceneManager)
1209{
1210 // Check all the resource value's scene manager, and update as necessary.
1211 if (sceneManager) {
1212 QQuick3DObjectPrivate::refSceneManager(obj: m_albedoMap, mgr&: *sceneManager);
1213 QQuick3DObjectPrivate::refSceneManager(obj: m_emissiveMap, mgr&: *sceneManager);
1214 QQuick3DObjectPrivate::refSceneManager(obj: m_glossinessMap, mgr&: *sceneManager);
1215 QQuick3DObjectPrivate::refSceneManager(obj: m_opacityMap, mgr&: *sceneManager);
1216 QQuick3DObjectPrivate::refSceneManager(obj: m_normalMap, mgr&: *sceneManager);
1217 QQuick3DObjectPrivate::refSceneManager(obj: m_specularMap, mgr&: *sceneManager);
1218 QQuick3DObjectPrivate::refSceneManager(obj: m_occlusionMap, mgr&: *sceneManager);
1219 QQuick3DObjectPrivate::refSceneManager(obj: m_heightMap, mgr&: *sceneManager);
1220 QQuick3DObjectPrivate::refSceneManager(obj: m_clearcoatMap, mgr&: *sceneManager);
1221 QQuick3DObjectPrivate::refSceneManager(obj: m_clearcoatRoughnessMap, mgr&: *sceneManager);
1222 QQuick3DObjectPrivate::refSceneManager(obj: m_clearcoatNormalMap, mgr&: *sceneManager);
1223 QQuick3DObjectPrivate::refSceneManager(obj: m_transmissionMap, mgr&: *sceneManager);
1224 QQuick3DObjectPrivate::refSceneManager(obj: m_thicknessMap, mgr&: *sceneManager);
1225 } else {
1226 QQuick3DObjectPrivate::derefSceneManager(obj: m_albedoMap);
1227 QQuick3DObjectPrivate::derefSceneManager(obj: m_emissiveMap);
1228 QQuick3DObjectPrivate::derefSceneManager(obj: m_glossinessMap);
1229 QQuick3DObjectPrivate::derefSceneManager(obj: m_opacityMap);
1230 QQuick3DObjectPrivate::derefSceneManager(obj: m_normalMap);
1231 QQuick3DObjectPrivate::derefSceneManager(obj: m_specularMap);
1232 QQuick3DObjectPrivate::derefSceneManager(obj: m_occlusionMap);
1233 QQuick3DObjectPrivate::derefSceneManager(obj: m_heightMap);
1234 QQuick3DObjectPrivate::derefSceneManager(obj: m_clearcoatMap);
1235 QQuick3DObjectPrivate::derefSceneManager(obj: m_clearcoatRoughnessMap);
1236 QQuick3DObjectPrivate::derefSceneManager(obj: m_clearcoatNormalMap);
1237 QQuick3DObjectPrivate::derefSceneManager(obj: m_transmissionMap);
1238 QQuick3DObjectPrivate::derefSceneManager(obj: m_thicknessMap);
1239 }
1240}
1241
1242void QQuick3DSpecularGlossyMaterial::markDirty(QQuick3DSpecularGlossyMaterial::DirtyType type)
1243{
1244 if (!(m_dirtyAttributes & quint32(type))) {
1245 m_dirtyAttributes |= quint32(type);
1246 update();
1247 }
1248}
1249
1250float QQuick3DSpecularGlossyMaterial::clearcoatAmount() const
1251{
1252 return m_clearcoatAmount;
1253}
1254
1255void QQuick3DSpecularGlossyMaterial::setClearcoatAmount(float newClearcoatAmount)
1256{
1257 if (qFuzzyCompare(p1: m_clearcoatAmount, p2: newClearcoatAmount))
1258 return;
1259 m_clearcoatAmount = newClearcoatAmount;
1260 emit clearcoatAmountChanged();
1261 markDirty(type: ClearcoatDirty);
1262}
1263
1264QQuick3DTexture *QQuick3DSpecularGlossyMaterial::clearcoatMap() const
1265{
1266 return m_clearcoatMap;
1267}
1268
1269void QQuick3DSpecularGlossyMaterial::setClearcoatMap(QQuick3DTexture *newClearcoatMap)
1270{
1271 if (m_clearcoatMap == newClearcoatMap)
1272 return;
1273
1274 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSpecularGlossyMaterial::setClearcoatMap, newO: newClearcoatMap, oldO: m_clearcoatMap);
1275
1276 m_clearcoatMap = newClearcoatMap;
1277 emit clearcoatMapChanged();
1278 markDirty(type: ClearcoatDirty);
1279}
1280
1281QQuick3DMaterial::TextureChannelMapping QQuick3DSpecularGlossyMaterial::clearcoatChannel() const
1282{
1283 return m_clearcoatChannel;
1284}
1285
1286void QQuick3DSpecularGlossyMaterial::setClearcoatChannel(QQuick3DMaterial::TextureChannelMapping newClearcoatChannel)
1287{
1288 if (m_clearcoatChannel == newClearcoatChannel)
1289 return;
1290 m_clearcoatChannel = newClearcoatChannel;
1291 emit clearcoatChannelChanged();
1292 markDirty(type: ClearcoatDirty);
1293}
1294
1295float QQuick3DSpecularGlossyMaterial::clearcoatRoughnessAmount() const
1296{
1297 return m_clearcoatRoughnessAmount;
1298}
1299
1300void QQuick3DSpecularGlossyMaterial::setClearcoatRoughnessAmount(float newClearcoatRoughnessAmount)
1301{
1302 if (qFuzzyCompare(p1: m_clearcoatRoughnessAmount, p2: newClearcoatRoughnessAmount))
1303 return;
1304 m_clearcoatRoughnessAmount = newClearcoatRoughnessAmount;
1305 emit clearcoatRoughnessAmountChanged();
1306 markDirty(type: ClearcoatDirty);
1307}
1308
1309QQuick3DMaterial::TextureChannelMapping QQuick3DSpecularGlossyMaterial::clearcoatRoughnessChannel() const
1310{
1311 return m_clearcoatRoughnessChannel;
1312}
1313
1314void QQuick3DSpecularGlossyMaterial::setClearcoatRoughnessChannel(QQuick3DMaterial::TextureChannelMapping newClearcoatRoughnessChannel)
1315{
1316 if (m_clearcoatRoughnessChannel == newClearcoatRoughnessChannel)
1317 return;
1318 m_clearcoatRoughnessChannel = newClearcoatRoughnessChannel;
1319 emit clearcoatRoughnessChannelChanged();
1320 markDirty(type: ClearcoatDirty);
1321}
1322
1323QQuick3DTexture *QQuick3DSpecularGlossyMaterial::clearcoatRoughnessMap() const
1324{
1325 return m_clearcoatRoughnessMap;
1326}
1327
1328void QQuick3DSpecularGlossyMaterial::setClearcoatRoughnessMap(QQuick3DTexture *newClearcoatRoughnessMap)
1329{
1330 if (m_clearcoatRoughnessMap == newClearcoatRoughnessMap)
1331 return;
1332
1333 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSpecularGlossyMaterial::setClearcoatRoughnessMap, newO: newClearcoatRoughnessMap, oldO: m_clearcoatRoughnessMap);
1334
1335 m_clearcoatRoughnessMap = newClearcoatRoughnessMap;
1336 emit clearcoatRoughnessMapChanged();
1337 markDirty(type: ClearcoatDirty);
1338}
1339
1340QQuick3DTexture *QQuick3DSpecularGlossyMaterial::clearcoatNormalMap() const
1341{
1342 return m_clearcoatNormalMap;
1343}
1344
1345void QQuick3DSpecularGlossyMaterial::setClearcoatNormalMap(QQuick3DTexture *newClearcoatNormalMap)
1346{
1347 if (m_clearcoatNormalMap == newClearcoatNormalMap)
1348 return;
1349
1350 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSpecularGlossyMaterial::setClearcoatNormalMap, newO: newClearcoatNormalMap, oldO: m_clearcoatNormalMap);
1351
1352 m_clearcoatNormalMap = newClearcoatNormalMap;
1353 emit clearcoatNormalMapChanged();
1354 markDirty(type: ClearcoatDirty);
1355}
1356
1357float QQuick3DSpecularGlossyMaterial::transmissionFactor() const
1358{
1359 return m_transmissionFactor;
1360}
1361
1362void QQuick3DSpecularGlossyMaterial::setTransmissionFactor(float newTransmissionFactor)
1363{
1364 if (qFuzzyCompare(p1: m_transmissionFactor, p2: newTransmissionFactor))
1365 return;
1366 m_transmissionFactor = newTransmissionFactor;
1367 emit transmissionFactorChanged();
1368 markDirty(type: TransmissionDirty);
1369}
1370
1371QQuick3DTexture *QQuick3DSpecularGlossyMaterial::transmissionMap() const
1372{
1373 return m_transmissionMap;
1374}
1375
1376void QQuick3DSpecularGlossyMaterial::setTransmissionMap(QQuick3DTexture *newTransmissionMap)
1377{
1378 if (m_transmissionMap == newTransmissionMap)
1379 return;
1380
1381 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSpecularGlossyMaterial::setTransmissionMap, newO: newTransmissionMap, oldO: m_transmissionMap);
1382
1383 m_transmissionMap = newTransmissionMap;
1384 emit transmissionMapChanged();
1385 markDirty(type: TransmissionDirty);
1386}
1387
1388QQuick3DMaterial::TextureChannelMapping QQuick3DSpecularGlossyMaterial::transmissionChannel() const
1389{
1390 return m_transmissionChannel;
1391}
1392
1393void QQuick3DSpecularGlossyMaterial::setTransmissionChannel(QQuick3DMaterial::TextureChannelMapping newTransmissionChannel)
1394{
1395 if (m_transmissionChannel == newTransmissionChannel)
1396 return;
1397 m_transmissionChannel = newTransmissionChannel;
1398 emit transmissionChannelChanged();
1399 markDirty(type: TransmissionDirty);
1400}
1401
1402float QQuick3DSpecularGlossyMaterial::thicknessFactor() const
1403{
1404 return m_thicknessFactor;
1405}
1406
1407void QQuick3DSpecularGlossyMaterial::setThicknessFactor(float newThicknessFactor)
1408{
1409 if (qFuzzyCompare(p1: m_thicknessFactor, p2: newThicknessFactor))
1410 return;
1411 m_thicknessFactor = newThicknessFactor;
1412 emit thicknessFactorChanged();
1413 markDirty(type: VolumeDirty);
1414}
1415
1416QQuick3DTexture *QQuick3DSpecularGlossyMaterial::thicknessMap() const
1417{
1418 return m_thicknessMap;
1419}
1420
1421void QQuick3DSpecularGlossyMaterial::setThicknessMap(QQuick3DTexture *newThicknessMap)
1422{
1423 if (m_thicknessMap == newThicknessMap)
1424 return;
1425
1426 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DSpecularGlossyMaterial::setThicknessMap, newO: newThicknessMap, oldO: m_thicknessMap);
1427
1428 m_thicknessMap = newThicknessMap;
1429 emit thicknessMapChanged();
1430 markDirty(type: VolumeDirty);
1431}
1432
1433QQuick3DMaterial::TextureChannelMapping QQuick3DSpecularGlossyMaterial::thicknessChannel() const
1434{
1435 return m_thicknessChannel;
1436}
1437
1438void QQuick3DSpecularGlossyMaterial::setThicknessChannel(QQuick3DMaterial::TextureChannelMapping newThicknessChannel)
1439{
1440 if (m_thicknessChannel == newThicknessChannel)
1441 return;
1442 m_thicknessChannel = newThicknessChannel;
1443 emit thicknessChannelChanged();
1444 markDirty(type: VolumeDirty);
1445}
1446
1447float QQuick3DSpecularGlossyMaterial::attenuationDistance() const
1448{
1449 return m_attenuationDistance;
1450}
1451
1452void QQuick3DSpecularGlossyMaterial::setAttenuationDistance(float newAttenuationDistance)
1453{
1454 if (qFuzzyCompare(p1: m_attenuationDistance, p2: newAttenuationDistance))
1455 return;
1456 m_attenuationDistance = newAttenuationDistance;
1457 emit attenuationDistanceChanged();
1458 markDirty(type: VolumeDirty);
1459}
1460
1461QColor QQuick3DSpecularGlossyMaterial::attenuationColor() const
1462{
1463 return m_attenuationColor;
1464}
1465
1466bool QQuick3DSpecularGlossyMaterial::vertexColorsEnabled() const
1467{
1468 return m_vertexColorsEnabled;
1469}
1470
1471void QQuick3DSpecularGlossyMaterial::setAttenuationColor(const QColor &newAttenuationColor)
1472{
1473 if (m_attenuationColor == newAttenuationColor)
1474 return;
1475 m_attenuationColor = newAttenuationColor;
1476 emit attenuationColorChanged();
1477 markDirty(type: VolumeDirty);
1478}
1479
1480void QQuick3DSpecularGlossyMaterial::setVertexColorsEnabled(bool vertexColors)
1481{
1482 if (m_vertexColorsEnabled == vertexColors)
1483 return;
1484
1485 m_vertexColorsEnabled = vertexColors;
1486 emit vertexColorsEnabledChanged(vertexColorsEnabled: m_vertexColorsEnabled);
1487 markDirty(type: VertexColorsDirty);
1488}
1489
1490QT_END_NAMESPACE
1491

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